@statsbygg/layout 0.1.11 → 0.1.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +2 -20
- package/dist/index.js +167 -70
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -23,12 +23,14 @@ type GlobalState = {
|
|
|
23
23
|
theme: Theme;
|
|
24
24
|
locale: string;
|
|
25
25
|
isMenuOpen: boolean;
|
|
26
|
+
zone: string | null;
|
|
26
27
|
breadcrumbs: BreadcrumbItem[] | null;
|
|
27
28
|
setUser: (user: GlobalState['user']) => void;
|
|
28
29
|
setTheme: (theme: Theme) => void;
|
|
29
30
|
setLocale: (locale: string) => void;
|
|
30
31
|
setIsMenuOpen: (isOpen: boolean) => void;
|
|
31
32
|
toggleMenu: () => void;
|
|
33
|
+
setZone: (zone: string) => void;
|
|
32
34
|
setBreadcrumbs: (breadcrumbs: BreadcrumbItem[] | null) => void;
|
|
33
35
|
initialize: () => void | Promise<void>;
|
|
34
36
|
};
|
|
@@ -46,26 +48,6 @@ declare const useGlobalStore: zustand.UseBoundStore<Omit<zustand.StoreApi<Global
|
|
|
46
48
|
};
|
|
47
49
|
}>;
|
|
48
50
|
|
|
49
|
-
/**
|
|
50
|
-
* Custom hook to override the default breadcrumb generation for a specific page.
|
|
51
|
-
* Automatically resets breadcrumbs to null on unmount to restore default behavior
|
|
52
|
-
* for subsequent pages.
|
|
53
|
-
*
|
|
54
|
-
* @param breadcrumbs - Array of breadcrumb items to display
|
|
55
|
-
*
|
|
56
|
-
* @example
|
|
57
|
-
* ```tsx
|
|
58
|
-
* function MyPage({ data }) {
|
|
59
|
-
* useBreadcrumbs([
|
|
60
|
-
* { label: 'Hjem', href: '/' },
|
|
61
|
-
* { label: 'Parent', href: '/parent' },
|
|
62
|
-
* { label: data.name, href: '#' }
|
|
63
|
-
* ]);
|
|
64
|
-
*
|
|
65
|
-
* return <div>Page content</div>;
|
|
66
|
-
* }
|
|
67
|
-
* ```
|
|
68
|
-
*/
|
|
69
51
|
declare function useBreadcrumbs(breadcrumbs: BreadcrumbItem[]): void;
|
|
70
52
|
|
|
71
53
|
export { type GlobalState, RootLayout, type RootLayoutProps, useBreadcrumbs, useGlobalStore };
|
package/dist/index.js
CHANGED
|
@@ -151,6 +151,10 @@ function getZoneFromPathname(pathname) {
|
|
|
151
151
|
if (pathname.startsWith("/lokaler")) return "lokaler";
|
|
152
152
|
return "sbno";
|
|
153
153
|
}
|
|
154
|
+
function getZonePrefixBreadcrumbs(zone) {
|
|
155
|
+
const zoneRoot = getZoneRoot(zone);
|
|
156
|
+
return getBreadcrumbs(zone, zoneRoot);
|
|
157
|
+
}
|
|
154
158
|
|
|
155
159
|
// src/store/globalState.ts
|
|
156
160
|
import { create } from "zustand";
|
|
@@ -161,6 +165,7 @@ var creator = (set, get) => ({
|
|
|
161
165
|
theme: "light",
|
|
162
166
|
locale: "no",
|
|
163
167
|
isMenuOpen: false,
|
|
168
|
+
zone: null,
|
|
164
169
|
breadcrumbs: null,
|
|
165
170
|
setUser: (user) => set({ user }),
|
|
166
171
|
setTheme: (theme) => {
|
|
@@ -172,6 +177,7 @@ var creator = (set, get) => ({
|
|
|
172
177
|
setLocale: (locale) => set({ locale }),
|
|
173
178
|
setIsMenuOpen: (isMenuOpen) => set({ isMenuOpen }),
|
|
174
179
|
toggleMenu: () => set((state) => ({ isMenuOpen: !state.isMenuOpen })),
|
|
180
|
+
setZone: (zone) => set({ zone }),
|
|
175
181
|
setBreadcrumbs: (breadcrumbs) => set({ breadcrumbs }),
|
|
176
182
|
initialize: () => {
|
|
177
183
|
if (typeof document !== "undefined" && ALLOW_DARK_THEME) {
|
|
@@ -191,6 +197,34 @@ var useGlobalStore = create()(
|
|
|
191
197
|
})
|
|
192
198
|
);
|
|
193
199
|
|
|
200
|
+
// src/locales/translations.ts
|
|
201
|
+
var translations = {
|
|
202
|
+
no: {
|
|
203
|
+
"common.menu": "Meny",
|
|
204
|
+
"common.close": "Lukk",
|
|
205
|
+
"common.search": "S\xF8k",
|
|
206
|
+
"common.searchLabel": "S\xF8k",
|
|
207
|
+
"common.youAreHere": "Du er her:",
|
|
208
|
+
"common.skipLink": "Hopp til hovedinnhold",
|
|
209
|
+
"common.home": "Hjem",
|
|
210
|
+
"footer.content": "Statsbygg Footer",
|
|
211
|
+
"menu.helpTitle": "Hva kan vi hjelpe deg med?",
|
|
212
|
+
"menu.mainMenuLabel": "Hovedmeny",
|
|
213
|
+
"menu.closeMenu": "Lukk meny",
|
|
214
|
+
"menu.openMenu": "\xC5pne meny"
|
|
215
|
+
}
|
|
216
|
+
};
|
|
217
|
+
|
|
218
|
+
// src/hooks/use-layout-translation.ts
|
|
219
|
+
function useLayoutTranslation() {
|
|
220
|
+
const locale = useGlobalStore((state) => state.locale);
|
|
221
|
+
const languageMap = translations[locale] || translations.no;
|
|
222
|
+
function t(key) {
|
|
223
|
+
return languageMap[key] || key;
|
|
224
|
+
}
|
|
225
|
+
return { t, locale };
|
|
226
|
+
}
|
|
227
|
+
|
|
194
228
|
// src/components/Breadcrumbs/Breadcrumbs.tsx
|
|
195
229
|
import { jsx } from "react/jsx-runtime";
|
|
196
230
|
function SbBreadcrumbs({ className, zone }) {
|
|
@@ -199,24 +233,32 @@ function SbBreadcrumbs({ className, zone }) {
|
|
|
199
233
|
const isDev = process.env.NODE_ENV === "development";
|
|
200
234
|
const prodUrl = "https://www.statsbygg.no";
|
|
201
235
|
const zoneRoot = getZoneRoot(zone);
|
|
236
|
+
const { t } = useLayoutTranslation();
|
|
202
237
|
const fullPath = isDev && zoneRoot !== "/" && !pathname.startsWith(zoneRoot) ? `${zoneRoot}${pathname}` : pathname;
|
|
203
238
|
const breadcrumbs = manualBreadcrumbs != null ? manualBreadcrumbs : getBreadcrumbs(zone, fullPath);
|
|
204
239
|
if (breadcrumbs.length <= 1) {
|
|
205
240
|
return null;
|
|
206
241
|
}
|
|
207
|
-
return /* @__PURE__ */ jsx(
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
{
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
242
|
+
return /* @__PURE__ */ jsx(
|
|
243
|
+
Breadcrumbs,
|
|
244
|
+
{
|
|
245
|
+
"aria-label": t("common.youAreHere"),
|
|
246
|
+
className: clsx(styles.breadcrumbs, className),
|
|
247
|
+
children: /* @__PURE__ */ jsx(Breadcrumbs.List, { children: breadcrumbs.map((crumb, index) => {
|
|
248
|
+
const isLast = index === breadcrumbs.length - 1;
|
|
249
|
+
const href = manualBreadcrumbs ? crumb.href : transformHrefForZone(crumb.href, zone, { isDev, prodUrl });
|
|
250
|
+
return /* @__PURE__ */ jsx(Breadcrumbs.Item, { children: /* @__PURE__ */ jsx(
|
|
251
|
+
Breadcrumbs.Link,
|
|
252
|
+
{
|
|
253
|
+
href,
|
|
254
|
+
"aria-current": isLast ? "page" : void 0,
|
|
255
|
+
className: isLast ? styles.currentLink : styles.link,
|
|
256
|
+
children: crumb.label
|
|
257
|
+
}
|
|
258
|
+
) }, crumb.href);
|
|
259
|
+
}) })
|
|
260
|
+
}
|
|
261
|
+
);
|
|
220
262
|
}
|
|
221
263
|
|
|
222
264
|
// src/components/MenuButton/MenuButton.tsx
|
|
@@ -423,6 +465,7 @@ function NavigationMenu({ zone }) {
|
|
|
423
465
|
const isMenuOpen = useGlobalStore((state) => state.isMenuOpen);
|
|
424
466
|
const setIsMenuOpen = useGlobalStore((state) => state.setIsMenuOpen);
|
|
425
467
|
const searchInputRef = useRef(null);
|
|
468
|
+
const { t } = useLayoutTranslation();
|
|
426
469
|
useEffect(() => {
|
|
427
470
|
if (!isMenuOpen) return;
|
|
428
471
|
const handleEscape = (event) => {
|
|
@@ -446,58 +489,95 @@ function NavigationMenu({ zone }) {
|
|
|
446
489
|
}
|
|
447
490
|
return /* @__PURE__ */ jsxs2(Fragment, { children: [
|
|
448
491
|
isMenuOpen && /* @__PURE__ */ jsx3("div", { className: styles3.backdrop, onClick: handleBackdropClick }),
|
|
449
|
-
/* @__PURE__ */ jsx3(
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
492
|
+
/* @__PURE__ */ jsx3(
|
|
493
|
+
"div",
|
|
494
|
+
{
|
|
495
|
+
className: `${styles3.menuOverlay} ${!isMenuOpen ? styles3.hidden : ""}`,
|
|
496
|
+
children: /* @__PURE__ */ jsxs2("div", { className: styles3.container, children: [
|
|
497
|
+
/* @__PURE__ */ jsxs2("div", { className: styles3.searchSection, children: [
|
|
498
|
+
/* @__PURE__ */ jsx3(Heading, { level: 1, children: t("menu.helpTitle") }),
|
|
499
|
+
/* @__PURE__ */ jsxs2(Search, { children: [
|
|
500
|
+
/* @__PURE__ */ jsx3(
|
|
501
|
+
Search.Input,
|
|
502
|
+
{
|
|
503
|
+
"aria-label": t("common.search"),
|
|
504
|
+
ref: searchInputRef,
|
|
505
|
+
value: searchValue,
|
|
506
|
+
onChange: (e) => setSearchValue(e.target.value),
|
|
507
|
+
placeholder: t("common.search"),
|
|
508
|
+
className: styles3.searchField
|
|
509
|
+
}
|
|
510
|
+
),
|
|
511
|
+
/* @__PURE__ */ jsx3(Search.Clear, {})
|
|
512
|
+
] })
|
|
513
|
+
] }),
|
|
453
514
|
/* @__PURE__ */ jsx3(
|
|
454
|
-
|
|
515
|
+
"nav",
|
|
455
516
|
{
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
517
|
+
className: styles3.menuSections,
|
|
518
|
+
"aria-label": t("menu.mainMenuLabel"),
|
|
519
|
+
children: NAVIGATION_MENU.map(
|
|
520
|
+
(section, sectionIndex) => {
|
|
521
|
+
var _a;
|
|
522
|
+
return /* @__PURE__ */ jsxs2(
|
|
523
|
+
"section",
|
|
524
|
+
{
|
|
525
|
+
className: styles3.section,
|
|
526
|
+
style: { animationDelay: `${0.15 + sectionIndex * 0.06}s` },
|
|
527
|
+
children: [
|
|
528
|
+
section.layout !== "subsections" && /* @__PURE__ */ jsx3(Heading, { level: 2, className: styles3.sectionHeader, children: section.title }),
|
|
529
|
+
section.layout === "subsections" && section.subsections ? /* @__PURE__ */ jsx3("div", { className: styles3.subsectionsGrid, children: section.subsections.map(
|
|
530
|
+
(subsection, subsectionIndex) => /* @__PURE__ */ jsxs2(
|
|
531
|
+
"div",
|
|
532
|
+
{
|
|
533
|
+
className: styles3.subsection,
|
|
534
|
+
children: [
|
|
535
|
+
/* @__PURE__ */ jsx3(
|
|
536
|
+
Heading,
|
|
537
|
+
{
|
|
538
|
+
level: 2,
|
|
539
|
+
className: styles3.subsectionHeader,
|
|
540
|
+
children: subsection.title
|
|
541
|
+
}
|
|
542
|
+
),
|
|
543
|
+
/* @__PURE__ */ jsx3("div", { className: styles3.subsectionItems, children: subsection.items.map((item, itemIndex) => /* @__PURE__ */ jsx3(
|
|
544
|
+
NavigationMenuItem,
|
|
545
|
+
{
|
|
546
|
+
item,
|
|
547
|
+
animationDelay: 150 + sectionIndex * 60 + subsectionIndex * 40 + itemIndex * 25,
|
|
548
|
+
compact: true
|
|
549
|
+
},
|
|
550
|
+
itemIndex
|
|
551
|
+
)) })
|
|
552
|
+
]
|
|
553
|
+
},
|
|
554
|
+
subsectionIndex
|
|
555
|
+
)
|
|
556
|
+
) }) : /* @__PURE__ */ jsx3(
|
|
557
|
+
"div",
|
|
558
|
+
{
|
|
559
|
+
className: sectionIndex === 2 ? styles3.itemsGridThreeCol : styles3.itemsGrid,
|
|
560
|
+
children: (_a = section.items) == null ? void 0 : _a.map((item, itemIndex) => /* @__PURE__ */ jsx3(
|
|
561
|
+
NavigationMenuItem,
|
|
562
|
+
{
|
|
563
|
+
item,
|
|
564
|
+
animationDelay: 150 + sectionIndex * 60 + itemIndex * 25
|
|
565
|
+
},
|
|
566
|
+
itemIndex
|
|
567
|
+
))
|
|
568
|
+
}
|
|
569
|
+
)
|
|
570
|
+
]
|
|
571
|
+
},
|
|
572
|
+
sectionIndex
|
|
573
|
+
);
|
|
574
|
+
}
|
|
575
|
+
)
|
|
462
576
|
}
|
|
463
|
-
)
|
|
464
|
-
/* @__PURE__ */ jsx3(Search.Clear, {})
|
|
577
|
+
)
|
|
465
578
|
] })
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
var _a;
|
|
469
|
-
return /* @__PURE__ */ jsxs2(
|
|
470
|
-
"section",
|
|
471
|
-
{
|
|
472
|
-
className: styles3.section,
|
|
473
|
-
style: { animationDelay: `${0.15 + sectionIndex * 0.06}s` },
|
|
474
|
-
children: [
|
|
475
|
-
section.layout !== "subsections" && /* @__PURE__ */ jsx3(Heading, { level: 2, className: styles3.sectionHeader, children: section.title }),
|
|
476
|
-
section.layout === "subsections" && section.subsections ? /* @__PURE__ */ jsx3("div", { className: styles3.subsectionsGrid, children: section.subsections.map((subsection, subsectionIndex) => /* @__PURE__ */ jsxs2("div", { className: styles3.subsection, children: [
|
|
477
|
-
/* @__PURE__ */ jsx3(Heading, { level: 2, className: styles3.subsectionHeader, children: subsection.title }),
|
|
478
|
-
/* @__PURE__ */ jsx3("div", { className: styles3.subsectionItems, children: subsection.items.map((item, itemIndex) => /* @__PURE__ */ jsx3(
|
|
479
|
-
NavigationMenuItem,
|
|
480
|
-
{
|
|
481
|
-
item,
|
|
482
|
-
animationDelay: 150 + sectionIndex * 60 + subsectionIndex * 40 + itemIndex * 25,
|
|
483
|
-
compact: true
|
|
484
|
-
},
|
|
485
|
-
itemIndex
|
|
486
|
-
)) })
|
|
487
|
-
] }, subsectionIndex)) }) : /* @__PURE__ */ jsx3("div", { className: sectionIndex === 2 ? styles3.itemsGridThreeCol : styles3.itemsGrid, children: (_a = section.items) == null ? void 0 : _a.map((item, itemIndex) => /* @__PURE__ */ jsx3(
|
|
488
|
-
NavigationMenuItem,
|
|
489
|
-
{
|
|
490
|
-
item,
|
|
491
|
-
animationDelay: 150 + sectionIndex * 60 + itemIndex * 25
|
|
492
|
-
},
|
|
493
|
-
itemIndex
|
|
494
|
-
)) })
|
|
495
|
-
]
|
|
496
|
-
},
|
|
497
|
-
sectionIndex
|
|
498
|
-
);
|
|
499
|
-
}) })
|
|
500
|
-
] }) })
|
|
579
|
+
}
|
|
580
|
+
)
|
|
501
581
|
] });
|
|
502
582
|
}
|
|
503
583
|
|
|
@@ -506,6 +586,7 @@ import { Fragment as Fragment2, jsx as jsx4, jsxs as jsxs3 } from "react/jsx-run
|
|
|
506
586
|
function MenuButton({ zone }) {
|
|
507
587
|
const isMenuOpen = useGlobalStore((state) => state.isMenuOpen);
|
|
508
588
|
const toggleMenu = useGlobalStore((state) => state.toggleMenu);
|
|
589
|
+
const { t } = useLayoutTranslation();
|
|
509
590
|
return /* @__PURE__ */ jsxs3(Fragment2, { children: [
|
|
510
591
|
/* @__PURE__ */ jsxs3(
|
|
511
592
|
Button,
|
|
@@ -513,10 +594,10 @@ function MenuButton({ zone }) {
|
|
|
513
594
|
variant: "primary",
|
|
514
595
|
onClick: toggleMenu,
|
|
515
596
|
"aria-expanded": isMenuOpen,
|
|
516
|
-
"aria-label": isMenuOpen ? "
|
|
597
|
+
"aria-label": isMenuOpen ? t("menu.closeMenu") : t("menu.openMenu"),
|
|
517
598
|
children: [
|
|
518
599
|
isMenuOpen ? /* @__PURE__ */ jsx4(X, { size: 20, "aria-hidden": "true" }) : /* @__PURE__ */ jsx4(Menu, { size: 20, "aria-hidden": "true" }),
|
|
519
|
-
isMenuOpen ? "
|
|
600
|
+
isMenuOpen ? t("common.close") : t("common.menu")
|
|
520
601
|
]
|
|
521
602
|
}
|
|
522
603
|
),
|
|
@@ -533,6 +614,7 @@ function GlobalHeader({ className, zone }) {
|
|
|
533
614
|
const setIsMenuOpen = useGlobalStore((state) => state.setIsMenuOpen);
|
|
534
615
|
const setTheme = useGlobalStore((state) => state.setTheme);
|
|
535
616
|
const theme = useGlobalStore((state) => state.theme);
|
|
617
|
+
const { t } = useLayoutTranslation();
|
|
536
618
|
function toggleDarkMode() {
|
|
537
619
|
setTheme(theme === "dark" ? "light" : "dark");
|
|
538
620
|
}
|
|
@@ -548,10 +630,10 @@ function GlobalHeader({ className, zone }) {
|
|
|
548
630
|
variant: "secondary",
|
|
549
631
|
onClick: () => setIsMenuOpen(true),
|
|
550
632
|
className: styles4.searchButton,
|
|
551
|
-
"aria-label": "
|
|
633
|
+
"aria-label": t("common.search"),
|
|
552
634
|
children: [
|
|
553
635
|
/* @__PURE__ */ jsx5(Search2, { size: 20, "aria-hidden": "true" }),
|
|
554
|
-
"
|
|
636
|
+
t("common.search")
|
|
555
637
|
]
|
|
556
638
|
}
|
|
557
639
|
)
|
|
@@ -569,7 +651,8 @@ import clsx3 from "clsx";
|
|
|
569
651
|
import styles5 from "./GlobalFooter.module.css";
|
|
570
652
|
import { jsx as jsx6 } from "react/jsx-runtime";
|
|
571
653
|
function GlobalFooter({ className }) {
|
|
572
|
-
|
|
654
|
+
const { t } = useLayoutTranslation();
|
|
655
|
+
return /* @__PURE__ */ jsx6("footer", { className: clsx3(styles5.footer, className), children: /* @__PURE__ */ jsx6("div", { className: styles5.container, children: /* @__PURE__ */ jsx6("div", { className: styles5.content, children: /* @__PURE__ */ jsx6(Paragraph, { children: t("footer.content") }) }) }) });
|
|
573
656
|
}
|
|
574
657
|
|
|
575
658
|
// src/components/RootLayout/RootLayout.tsx
|
|
@@ -582,7 +665,12 @@ function RootLayout({
|
|
|
582
665
|
className
|
|
583
666
|
}) {
|
|
584
667
|
const initialize = useGlobalStore((state) => state.initialize);
|
|
668
|
+
const setZone = useGlobalStore((state) => state.setZone);
|
|
585
669
|
const isMenuOpen = useGlobalStore((state) => state.isMenuOpen);
|
|
670
|
+
const { t } = useLayoutTranslation();
|
|
671
|
+
useEffect2(() => {
|
|
672
|
+
setZone(zone);
|
|
673
|
+
}, [zone, setZone]);
|
|
586
674
|
useEffect2(() => {
|
|
587
675
|
try {
|
|
588
676
|
const maybe = initialize();
|
|
@@ -596,7 +684,7 @@ function RootLayout({
|
|
|
596
684
|
}
|
|
597
685
|
}, [initialize]);
|
|
598
686
|
return /* @__PURE__ */ jsxs5("div", { className: clsx4(styles6.root, isMenuOpen && styles6.menuOpen, className), "data-zone": zone, children: [
|
|
599
|
-
/* @__PURE__ */ jsx7(SkipLink, { className: styles6.skipLink, href: "#main-content", children: "
|
|
687
|
+
/* @__PURE__ */ jsx7(SkipLink, { className: styles6.skipLink, href: "#main-content", children: t("common.skipLink") }),
|
|
600
688
|
/* @__PURE__ */ jsx7(GlobalHeader, { zone }),
|
|
601
689
|
/* @__PURE__ */ jsx7("main", { id: "main-content", tabIndex: -1, className: styles6.main, children }),
|
|
602
690
|
/* @__PURE__ */ jsx7(GlobalFooter, {})
|
|
@@ -604,15 +692,24 @@ function RootLayout({
|
|
|
604
692
|
}
|
|
605
693
|
|
|
606
694
|
// src/hooks/use-breadcrumbs.ts
|
|
607
|
-
import { useEffect as useEffect3 } from "react";
|
|
695
|
+
import { useEffect as useEffect3, useRef as useRef2 } from "react";
|
|
608
696
|
function useBreadcrumbs(breadcrumbs) {
|
|
609
697
|
const setBreadcrumbs = useGlobalStore((state) => state.setBreadcrumbs);
|
|
698
|
+
const zone = useGlobalStore((state) => state.zone);
|
|
699
|
+
const breadcrumbsStringified = JSON.stringify(breadcrumbs);
|
|
700
|
+
const hasSetBreadcrumbs = useRef2(false);
|
|
610
701
|
useEffect3(() => {
|
|
611
|
-
|
|
702
|
+
if (!zone || hasSetBreadcrumbs.current) return;
|
|
703
|
+
const zonePrefixBreadcrumbs = getZonePrefixBreadcrumbs(zone);
|
|
704
|
+
const parsedBreadcrumbs = JSON.parse(breadcrumbsStringified);
|
|
705
|
+
const fullBreadcrumbs = [...zonePrefixBreadcrumbs, ...parsedBreadcrumbs];
|
|
706
|
+
setBreadcrumbs(fullBreadcrumbs);
|
|
707
|
+
hasSetBreadcrumbs.current = true;
|
|
612
708
|
return () => {
|
|
613
709
|
setBreadcrumbs(null);
|
|
710
|
+
hasSetBreadcrumbs.current = false;
|
|
614
711
|
};
|
|
615
|
-
}, [
|
|
712
|
+
}, [zone, breadcrumbsStringified, setBreadcrumbs]);
|
|
616
713
|
}
|
|
617
714
|
export {
|
|
618
715
|
RootLayout,
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/components/RootLayout/RootLayout.tsx","../src/components/GlobalHeader/GlobalHeader.tsx","../src/components/Breadcrumbs/Breadcrumbs.tsx","../src/routes.ts","../src/store/globalState.ts","../src/components/MenuButton/MenuButton.tsx","../src/components/NavigationMenu/NavigationMenu.tsx","../src/navigationMenu.ts","../src/components/NavigationMenuItem/NavigationMenuItem.tsx","../src/components/GlobalFooter/GlobalFooter.tsx","../src/hooks/use-breadcrumbs.ts"],"sourcesContent":["'use client';\n\nimport { useEffect } from 'react';\nimport clsx from 'clsx';\nimport { GlobalHeader } from '../GlobalHeader';\nimport { GlobalFooter } from '../GlobalFooter';\nimport type { RootLayoutProps } from './RootLayout.types';\nimport styles from './RootLayout.module.css';\nimport { useGlobalStore } from '@/store/globalState';\nimport { SkipLink } from '@digdir/designsystemet-react';\n\nexport function RootLayout({\n children,\n zone, \n className,\n}: RootLayoutProps) {\n const initialize = useGlobalStore((state) => state.initialize);\n const isMenuOpen = useGlobalStore((state) => state.isMenuOpen); \n\n useEffect(() => {\n try {\n const maybe = initialize();\n if (maybe && typeof (maybe as Promise<void>).then === 'function') {\n (maybe as Promise<void>).catch((error) => {\n console.error('Failed to initialize global state:', error);\n });\n }\n } catch (error) {\n console.error('Failed to initialize global state:', error);\n }\n }, [initialize]);\n\n\n return (\n <div className={clsx(styles.root, isMenuOpen && styles.menuOpen, className)} data-zone={zone}>\n <SkipLink className={styles.skipLink} href='#main-content'>Hopp til hovedinnhold</SkipLink>\n <GlobalHeader zone={zone}/>\n <main id=\"main-content\" tabIndex={-1} className={styles.main}>{children}</main>\n <GlobalFooter />\n </div>\n );\n}\n","'use client';\n\nimport { Button, Link } from '@digdir/designsystemet-react';\nimport clsx from 'clsx';\nimport { Breadcrumbs } from '../Breadcrumbs';\nimport { MenuButton } from '../MenuButton';\nimport type { GlobalHeaderProps } from './GlobalHeader.types';\nimport styles from './GlobalHeader.module.css';\nimport { ALLOW_DARK_THEME, useGlobalStore } from '@/store/globalState';\nimport { Search } from 'lucide-react';\n\nexport function GlobalHeader({ className, zone }: GlobalHeaderProps) {\n const isMenuOpen = useGlobalStore((state) => state.isMenuOpen);\n const setIsMenuOpen = useGlobalStore((state) => state.setIsMenuOpen);\n const setTheme = useGlobalStore((state) => state.setTheme);\n const theme = useGlobalStore((state) => state.theme);\n \n // function for toggling darkmode lightmode with zustand store\n function toggleDarkMode() {\n setTheme(theme === 'dark' ? 'light' : 'dark');\n }\n\n\n return (\n <header className={clsx(styles.header, isMenuOpen && styles.menuOpen, className)}>\n <div className={styles.headerContainer}>\n <div className={styles.topBarContainer}>\n <Link href=\"https://www.statsbygg.no\">\n <img src={'https://dok.statsbygg.no/wp-content/uploads/2025/11/Statsbygg_logo.svg'} alt=\"Logo\" className={styles.logo} />\n </Link>\n <div className={styles.actionsContainer}>\n {!isMenuOpen && (\n <>\n {ALLOW_DARK_THEME && <Button onClick={toggleDarkMode} className={styles.themeToggleButton}>\n {theme === 'dark' ? '☀️' : '🌙'}\n </Button>}\n <Button\n variant=\"secondary\"\n onClick={() => setIsMenuOpen(true)}\n className={styles.searchButton}\n aria-label=\"Søk\"\n >\n <Search size={20} aria-hidden=\"true\" />\n Søk\n </Button></>\n )}\n <MenuButton zone={zone} />\n </div>\n </div>\n <Breadcrumbs zone={zone} />\n </div>\n </header>\n );\n}","'use client';\n\nimport { usePathname } from 'next/navigation';\nimport { Breadcrumbs } from '@digdir/designsystemet-react';\nimport clsx from 'clsx';\nimport type { BreadcrumbsProps } from './Breadcrumbs.types';\nimport styles from './Breadcrumbs.module.css';\nimport { getBreadcrumbs, getZoneRoot, transformHrefForZone } from '@/routes';\nimport { useGlobalStore } from '@/store/globalState';\n\nexport function SbBreadcrumbs({ className, zone }: BreadcrumbsProps) {\n const pathname = usePathname();\n const manualBreadcrumbs = useGlobalStore((state) => state.breadcrumbs);\n const isDev = process.env.NODE_ENV === 'development';\n const prodUrl = 'https://www.statsbygg.no';\n const zoneRoot = getZoneRoot(zone);\n \n const fullPath = isDev && zoneRoot !== '/' && !pathname.startsWith(zoneRoot)\n ? `${zoneRoot}${pathname}`\n : pathname;\n \n const breadcrumbs = manualBreadcrumbs ?? getBreadcrumbs(zone, fullPath);\n\n if (breadcrumbs.length <= 1) {\n return null;\n }\n\n return (\n <Breadcrumbs aria-label=\"Du er her:\" className={clsx(styles.breadcrumbs, className)}>\n <Breadcrumbs.List>\n {breadcrumbs.map((crumb, index) => {\n const isLast = index === breadcrumbs.length - 1;\n const href = manualBreadcrumbs \n ? crumb.href \n : transformHrefForZone(crumb.href, zone, { isDev, prodUrl });\n \n return (\n <Breadcrumbs.Item key={crumb.href}>\n <Breadcrumbs.Link\n href={href}\n aria-current={isLast ? 'page' : undefined}\n className={isLast ? styles.currentLink : styles.link}\n >\n {crumb.label}\n </Breadcrumbs.Link>\n </Breadcrumbs.Item>\n );\n })}\n </Breadcrumbs.List>\n </Breadcrumbs>\n );\n}","export type RouteNodeInput =\n | { segment: string; label: string; children?: RouteNodeInput[] }\n | { path: string; label: string; children?: RouteNodeInput[] };\n\nexport type RouteNode = {\n path: string;\n label: string;\n children?: RouteNode[];\n};\n\nexport type RouteDefinition = {\n path: string;\n label: string;\n zone: string;\n};\n\nconst ZONE_TREES_INPUT: Record<string, RouteNodeInput> = {\n sbno: {\n segment: '',// primary root route, no breadcrumb\n label: 'Hjem',\n children: [\n { segment: 'nyheter', label: 'Nyheter' },\n ],\n },\n lokaler: {\n segment: 'lokaler',\n label: 'Statens eide og leide lokaler',\n children: [\n {\n segment: 'lokalbruk', label: 'Lokalbruk'\n },\n { segment: 'veiledning', label: 'Veiledning' },\n { segment: 'statlige-eiendommer', label: 'Statlige eiendommer' },\n { segment: 'ledig-for-fremleie', label: 'Ledig for fremleie' },\n { segment: 'statistikk', label: 'Statistikk' },\n ],\n },\n};\n\n\ntype Key = `${string}:${string}`; // `${zone}:${absolutePath}`\n\nconst ROUTES_INDEX: Record<string, RouteDefinition[]> = {};\nconst PARENT_INDEX = new Map<Key, Key | null>(); // child -> parent\nconst ZONE_TREES: Record<string, RouteNode> = {}; // normalized absolute trees\n\nfunction isSegmentNode(n: RouteNodeInput): n is Extract<RouteNodeInput, { segment: string }> {\n return (n as any).segment !== undefined && (n as any).path === undefined;\n}\nfunction isPathNode(n: RouteNodeInput): n is Extract<RouteNodeInput, { path: string }> {\n return (n as any).path !== undefined;\n}\n\nfunction joinPath(base: string, seg: string): string {\n if (!base) return seg ? `/${seg}` : '/';\n return seg ? `${base.replace(/\\/+$/, '')}/${seg.replace(/^\\/+/, '')}` : base || '/';\n}\n\nfunction normalizeToAbsolute(node: RouteNodeInput, base = ''): RouteNode {\n const path = isSegmentNode(node)\n ? joinPath(base, node.segment)\n : isPathNode(node)\n ? (node.path === '' ? '/' : node.path)\n : '/';\n\n const children = (node.children ?? []).map((c) => normalizeToAbsolute(c, path));\n return { path, label: (node as any).label, children: children.length ? children : undefined };\n}\n\n(function buildAll() {\n // Normalize each zone tree to absolute paths\n Object.keys(ZONE_TREES_INPUT).forEach((zone) => {\n ZONE_TREES[zone] = normalizeToAbsolute(ZONE_TREES_INPUT[zone]);\n });\n\n // Build flat indexes + parent relationships\n function walk(zone: string, node: RouteNode, parentKey: Key | null) {\n const def: RouteDefinition = { zone, path: node.path, label: node.label };\n const key: Key = `${zone}:${node.path}`;\n ROUTES_INDEX[zone].push(def);\n PARENT_INDEX.set(key, parentKey);\n for (const child of node.children ?? []) {\n walk(zone, child, key);\n }\n }\n\n (Object.keys(ZONE_TREES) as string[]).forEach((zone) => {\n ROUTES_INDEX[zone] = [];\n walk(zone, ZONE_TREES[zone], null);\n });\n})();\n\n\nfunction findBestMatch(zone: string, pathname: string): RouteDefinition | undefined {\n const list = ROUTES_INDEX[zone] ?? [];\n let best: RouteDefinition | undefined;\n\n for (const r of list) {\n if (pathname === r.path) {\n best = r; // exact wins\n break;\n }\n if (pathname.startsWith(r.path.endsWith('/') ? r.path : r.path + '/')) {\n if (!best || r.path.length > best.path.length) best = r;\n }\n }\n // fallback: zone root\n return best ?? list.find((r) => r.path === ZONE_TREES[zone]?.path);\n}\n\nexport function getZoneRoutes(zone: string): RouteDefinition[] {\n return ROUTES_INDEX[zone] ?? [];\n}\n\n// Top-level links for a zone’s menu (children of the zone root)\nexport function getZoneMenuRoutes(zone: string): RouteDefinition[] {\n const root = ZONE_TREES[zone];\n const children = root?.children ?? [];\n return children.map((c) => ({ zone, path: c.path, label: c.label }));\n}\n\nexport function getAllZones(): string[] {\n return Object.keys(ZONE_TREES);\n}\n\nexport function getZoneRoot(zone: string): string {\n return ZONE_TREES[zone]?.path || '/';\n}\n\n// prettify dynamic slug labels\nfunction labelFromSlug(slug: string): string {\n try {\n const s = decodeURIComponent(slug).replace(/[-_]+/g, ' ').trim();\n return s ? s.charAt(0).toUpperCase() + s.slice(1) : slug;\n } catch {\n return slug;\n }\n}\n\nexport function getBreadcrumbs(\n zone: string,\n pathname: string\n): Array<{ label: string; href: string }> {\n\n const normalizedPathname = pathname === '/' ? pathname : pathname.replace(/\\/+$/, '');\n\n // sbno root has no crumbs\n if (zone === 'sbno' && normalizedPathname === '/') return [];\n\n const match = findBestMatch(zone, normalizedPathname);\n if (!match) return [];\n\n const chain: RouteDefinition[] = [];\n let key: Key | undefined = `${zone}:${match.path}`;\n while (key) {\n const parentKey = PARENT_INDEX.get(key);\n const [z, p] = key.split(':') as [string, string];\n const def = (ROUTES_INDEX[z] ?? []).find((r) => r.path === p);\n if (def) chain.unshift(def);\n key = parentKey ?? undefined;\n }\n\n const homeRoute = (ROUTES_INDEX.sbno ?? []).find((r) => r.path === '/');\n if (\n homeRoute &&\n !(chain.length === 1 && chain[0].zone === 'sbno' && chain[0].path === '/') &&\n (chain.length === 0 || chain[0].path !== homeRoute.path)\n ) {\n chain.unshift(homeRoute);\n }\n\n // If the pathname is deeper than the best static match, add a dynamic tail\n const last = chain[chain.length - 1];\n if (last && normalizedPathname !== last.path && normalizedPathname.startsWith(last.path.endsWith('/') ? last.path : last.path + '/')) {\n const segments = normalizedPathname.split('/').filter(Boolean);\n const tail = segments[segments.length - 1];\n chain.push({ zone, path: normalizedPathname, label: labelFromSlug(tail) });\n }\n\n return chain.map((r) => ({ label: r.label, href: r.path }));\n}\n\nexport function transformHrefForZone(\n targetPath: string,\n currentZone: string,\n options: {\n isDev: boolean;\n prodUrl?: string;\n }\n): string {\n const { isDev, prodUrl } = options;\n\n const targetZone = getZoneFromPathname(targetPath);\n const isCrossZone = targetZone !== currentZone;\n\n if (isCrossZone && isDev && prodUrl) {\n return `${prodUrl}${targetPath}`;\n }\n\n const currentZoneRoot = getZoneRoot(currentZone);\n if (!isCrossZone && isDev && currentZoneRoot !== '/') {\n return targetPath.replace(currentZoneRoot, '') || '/';\n }\n\n return targetPath;\n}\n\nexport function getZoneFromPathname(pathname: string): string {\n if (pathname.startsWith('/lokaler')) return 'lokaler';\n return 'sbno';\n}","import { create, StateCreator } from 'zustand';\nimport { persist, createJSONStorage } from 'zustand/middleware';\n\nexport type Theme = 'light' | 'dark' | 'system';\n\nexport const ALLOW_DARK_THEME = false;\n\nexport type BreadcrumbItem = {\n label: string;\n href: string;\n};\n\nexport type GlobalState = {\n user?: { id: string; name?: string } | null;\n theme: Theme;\n locale: string;\n isMenuOpen: boolean;\n breadcrumbs: BreadcrumbItem[] | null;\n setUser: (user: GlobalState['user']) => void;\n setTheme: (theme: Theme) => void;\n setLocale: (locale: string) => void;\n setIsMenuOpen: (isOpen: boolean) => void;\n toggleMenu: () => void;\n setBreadcrumbs: (breadcrumbs: BreadcrumbItem[] | null) => void;\n initialize: () => void | Promise<void>;\n};\n\nconst creator: StateCreator<GlobalState, [['zustand/persist', unknown]]> = (set, get) => ({\n user: null,\n theme: 'light',\n locale: 'no',\n isMenuOpen: false,\n breadcrumbs: null,\n setUser: (user) => set({ user }),\n setTheme: (theme) => {\n set({ theme: ALLOW_DARK_THEME ? theme : 'light' });\n if (typeof document !== 'undefined' && ALLOW_DARK_THEME) {\n document.documentElement.setAttribute('data-color-scheme', theme);\n }\n },\n setLocale: (locale) => set({ locale }),\n setIsMenuOpen: (isMenuOpen) => set({ isMenuOpen }),\n toggleMenu: () => set((state) => ({ isMenuOpen: !state.isMenuOpen })),\n setBreadcrumbs: (breadcrumbs) => set({ breadcrumbs }),\n initialize: () => {\n if (typeof document !== 'undefined' && ALLOW_DARK_THEME) {\n document.documentElement.setAttribute('data-color-scheme', get().theme);\n }\n },\n});\n\nexport const useGlobalStore = create<GlobalState>()(\n persist(creator, {\n name: 'statsbygg-global-state',\n storage: createJSONStorage(() => localStorage),\n partialize: (state) => ({\n user: state.user,\n theme: ALLOW_DARK_THEME ? state.theme : 'light',\n locale: state.locale,\n }),\n })\n);","'use client';\n\nimport { Button } from '@digdir/designsystemet-react';\nimport { Menu, X } from 'lucide-react';\nimport { useGlobalStore } from '@/store/globalState';\nimport { NavigationMenu } from '../NavigationMenu';\nimport type { MenuButtonProps } from './MenuButton.types';\n\nexport function MenuButton({ zone }: MenuButtonProps) {\n const isMenuOpen = useGlobalStore((state) => state.isMenuOpen);\n const toggleMenu = useGlobalStore((state) => state.toggleMenu);\n\n return (\n <>\n <Button\n variant='primary'\n onClick={toggleMenu}\n aria-expanded={isMenuOpen}\n aria-label={isMenuOpen ? 'Lukk meny' : 'Åpne meny'}\n >\n {isMenuOpen ? <X size={20} aria-hidden=\"true\" /> : <Menu size={20} aria-hidden=\"true\" />}\n {isMenuOpen ? 'Lukk' : 'Meny'}\n </Button>\n <NavigationMenu zone={zone} />\n </>\n );\n}","'use client';\nimport { useState, useEffect, useRef } from 'react';\nimport { Heading, Search, Textfield } from '@digdir/designsystemet-react';\nimport { NAVIGATION_MENU } from '../../navigationMenu';\nimport { NavigationMenuItem } from '../NavigationMenuItem/NavigationMenuItem';\nimport { useGlobalStore } from '../../store/globalState';\nimport styles from './NavigationMenu.module.css';\nimport { MenuSection, NavigationMenuProps } from './NavigationMenu.types';\n\nexport function NavigationMenu({ zone }: NavigationMenuProps) {\n const [searchValue, setSearchValue] = useState('');\n const isMenuOpen = useGlobalStore((state) => state.isMenuOpen);\n const setIsMenuOpen = useGlobalStore((state) => state.setIsMenuOpen);\n const searchInputRef = useRef<HTMLInputElement>(null);\n\nuseEffect(() => {\n if (!isMenuOpen) return;\n\n const handleEscape = (event: KeyboardEvent) => {\n if (event.key === 'Escape') {\n setIsMenuOpen(false);\n }\n };\n\n setTimeout(() => {\n searchInputRef.current?.focus();\n }, 100);\n\n document.addEventListener('keydown', handleEscape);\n\n return () => {\n document.removeEventListener('keydown', handleEscape);\n };\n}, [setIsMenuOpen, isMenuOpen]);\n\n function handleBackdropClick(e: React.MouseEvent<HTMLDivElement>) {\n if (e.target === e.currentTarget) {\n setIsMenuOpen(false);\n }\n }\n\n return (\n <>\n {isMenuOpen && <div className={styles.backdrop} onClick={handleBackdropClick} />}\n <div className={`${styles.menuOverlay} ${!isMenuOpen ? styles.hidden : ''}`}>\n <div className={styles.container}>\n <div className={styles.searchSection}>\n <Heading level={1}>\n Hva kan vi hjelpe deg med?\n </Heading>\n <Search>\n <Search.Input aria-label='Søk' ref={searchInputRef}\n value={searchValue}\n onChange={(e) => setSearchValue(e.target.value)}\n placeholder=\"Søk\"\n className={styles.searchField}\n />\n <Search.Clear />\n </Search>\n </div>\n\n <nav className={styles.menuSections} aria-label=\"Hovedmeny\">\n {NAVIGATION_MENU.map((section: MenuSection, sectionIndex: number) => (\n <section\n key={sectionIndex}\n className={styles.section}\n style={{ animationDelay: `${0.15 + (sectionIndex * 0.06)}s` }}\n >\n {/* Only show section header for non-subsection layouts */}\n {section.layout !== 'subsections' && (\n <Heading level={2} className={styles.sectionHeader}>\n {section.title}\n </Heading>\n )}\n\n {section.layout === 'subsections' && section.subsections ? (\n <div className={styles.subsectionsGrid}>\n {section.subsections.map((subsection, subsectionIndex) => (\n <div key={subsectionIndex} className={styles.subsection}>\n <Heading level={2} className={styles.subsectionHeader}>\n {subsection.title}\n </Heading>\n <div className={styles.subsectionItems}>\n {subsection.items.map((item, itemIndex) => (\n <NavigationMenuItem\n key={itemIndex}\n item={item}\n animationDelay={(150 + (sectionIndex * 60)) + (subsectionIndex * 40) + (itemIndex * 25)}\n compact\n />\n ))}\n </div>\n </div>\n ))}\n </div>\n ) : (\n <div className={sectionIndex === 2 ? styles.itemsGridThreeCol : styles.itemsGrid}>\n {section.items?.map((item, itemIndex) => (\n <NavigationMenuItem\n key={itemIndex}\n item={item}\n animationDelay={(150 + (sectionIndex * 60)) + (itemIndex * 25)}\n />\n ))}\n </div>\n )}\n </section>\n ))}\n </nav>\n </div>\n </div>\n </>\n );\n}","export interface MenuItem {\n label: string;\n href: string;\n external?: boolean;\n children?: MenuItem[];\n}\n\nexport interface MenuSubsection {\n title: string;\n items: MenuItem[];\n}\n\nexport interface MenuSection {\n title: string;\n layout?: 'columns' | 'subsections';\n items?: MenuItem[];\n subsections?: MenuSubsection[];\n}\n\nexport const NAVIGATION_MENU: MenuSection[] = [\n {\n title: 'Våre tjenester',\n layout: 'columns',\n items: [\n {\n label: 'Statens eide og leide lokaler',\n href: '/lokaler',\n children: [\n { label: 'Lokalbruk', href: '/lokaler/lokalbruk' },\n { label: 'Statlige eiendommer', href: '/lokaler/statlige-eiendommer' },\n { label: 'Ledig for fremleie', href: '/lokaler/ledig-for-fremleie' },\n { label: 'Statistikk for lokalbruk', href: '/lokaler/statistikk' },\n { label: 'Veiledning', href: '/lokaler/veiledning' },\n ],\n },\n {\n label: 'For leietakere',\n href: '/for-leietakere',\n children: [\n { label: 'Leieveileder', href: '/leietakere/leieveileder' },\n { label: 'Lenke til underside', href: '/leietakere/lenke1' },\n { label: 'Lenke til underside', href: '/leietakere/lenke2' },\n ],\n },\n {\n label: 'For byggebransjen',\n href: '/byggebransjen',\n children: [\n { label: 'Våre krav', href: '/byggebransjen/vare-krav' },\n { label: 'BIM', href: '/byggebransjen/bim' },\n { label: 'ByggBoks', href: '/byggebransjen/byggboks' },\n { label: 'Lenke til underside', href: '/byggebransjen/lenke' },\n ],\n },\n {\n label: 'Karriere',\n href: '/karriere',\n children: [\n { label: 'Ledige stillinger', href: '/karriere/ledige-stillinger' },\n { label: 'Å jobbe hos oss', href: '/karriere/jobbe-hos-oss' },\n { label: 'Møt en statsbygger', href: '/karriere/mot-en-statsbygger' },\n { label: 'Summer internship', href: '/karriere/summer-internship' },\n { label: 'Studenter og lærlinger', href: '/karriere/studenter-og-laerlinger' },\n ],\n },\n ],\n },\n {\n title: 'Informasjon om statsbygg',\n layout: 'subsections',\n subsections: [\n {\n title: 'Informasjon om statsbygg',\n items: [\n { label: 'Om Statsbygg', href: '/om-statsbygg' },\n { label: 'Samfunnsansvar', href: '/samfunnsansvar' },\n { label: 'Tilgjengelighet', href: '/tilgjengelighet' },\n { label: 'About Statsbygg', href: '/about-statsbygg' },\n { label: 'Statsbygg birra', href: '/statsbygg-birra' },\n ],\n },\n {\n title: 'Kontakt oss',\n items: [\n { label: 'Kontakt oss', href: '/kontakt' },\n { label: 'Ansattsøk', href: '/ansattsok' },\n { label: 'For pressen', href: '/for-pressen' },\n { label: 'Varsling', href: '/varsling' },\n ],\n },\n {\n title: 'Arkiv',\n items: [\n { label: 'Nyheter', href: '/nyheter' },\n { label: 'Artikler om bygg', href: '/artikler-om-bygg' },\n { label: 'Dokumenter', href: '/dokumenter' },\n ],\n },\n ],\n },\n {\n title: 'Eksterne lenker',\n layout: 'columns',\n items: [\n {\n label: 'Statens lokaler',\n href: 'https://statensinnleie.no',\n external: true,\n },\n {\n label: 'Statens innleie',\n href: 'https://statensinnleie.no',\n external: true,\n },\n {\n label: 'MainManager FM',\n href: 'https://mainmanager.no',\n external: true,\n },\n {\n label: 'Offentlig postjournal',\n href: 'https://postjournal.no',\n external: true,\n },\n {\n label: 'SIMBA (BIM)',\n href: 'https://bim.statsbygg.no',\n external: true,\n },\n ],\n },\n];","import { Link, List } from '@digdir/designsystemet-react';\nimport { ExternalLink } from 'lucide-react';\nimport { MenuItem } from '../../navigationMenu';\nimport styles from './NavigationMenuItem.module.css';\nimport { NavigationMenuItemProps } from './NavigationMenuItem.types';\n\nexport function NavigationMenuItem({ item, animationDelay, compact = false }: NavigationMenuItemProps) {\n if (compact) {\n return (\n <div\n className={styles.itemColumn}\n style={{ animationDelay: `${animationDelay}ms` }}\n >\n <Link\n href={item.href}\n className={styles.compactLink}\n target={item.external ? '_blank' : undefined}\n rel={item.external ? 'noopener noreferrer' : undefined}\n >\n {item.label}\n {item.external && (\n <ExternalLink size={16} aria-hidden=\"true\" />\n )}\n </Link>\n </div>\n );\n }\n\n return (\n <div\n className={styles.itemColumn}\n style={{ animationDelay: `${animationDelay}ms` }}\n >\n <Link\n href={item.href}\n className={styles.parentLink}\n target={item.external ? '_blank' : undefined}\n rel={item.external ? 'noopener noreferrer' : undefined}\n >\n {item.label}\n {item.external && (\n <ExternalLink size={20} aria-hidden=\"true\" />\n )}\n </Link>\n\n {item.children && item.children.length > 0 && (\n <List.Unordered className={styles.childItems}>\n {item.children.map((child, childIndex) => (\n <List.Item\n key={childIndex}\n className={styles.childItem}\n style={{ animationDelay: `${animationDelay + 30 + (childIndex * 15)}ms` }}\n >\n <Link\n href={child.href}\n className={styles.childLink}\n target={child.external ? '_blank' : undefined}\n rel={child.external ? 'noopener noreferrer' : undefined}\n >\n {child.label}\n {child.external && (\n <ExternalLink size={20} aria-hidden=\"true\" />\n )}\n </Link>\n </List.Item>\n ))}\n </List.Unordered>\n )}\n </div>\n );\n}","'use client';\n\nimport { Paragraph } from '@digdir/designsystemet-react';\nimport clsx from 'clsx';\nimport type { GlobalFooterProps } from './GlobalFooter.types';\nimport styles from './GlobalFooter.module.css';\n\nexport function GlobalFooter({ className }: GlobalFooterProps) {\n\n return (\n <footer className={clsx(styles.footer, className)}>\n <div className={styles.container}>\n <div className={styles.content}>\n <Paragraph>\n Statsbygg Footer\n </Paragraph>\n\n\n </div>\n </div>\n </footer>\n );\n}","import { useEffect } from 'react';\nimport { useGlobalStore, BreadcrumbItem } from '../store/globalState';\n\n/**\n * Custom hook to override the default breadcrumb generation for a specific page.\n * Automatically resets breadcrumbs to null on unmount to restore default behavior\n * for subsequent pages.\n *\n * @param breadcrumbs - Array of breadcrumb items to display\n *\n * @example\n * ```tsx\n * function MyPage({ data }) {\n * useBreadcrumbs([\n * { label: 'Hjem', href: '/' },\n * { label: 'Parent', href: '/parent' },\n * { label: data.name, href: '#' }\n * ]);\n *\n * return <div>Page content</div>;\n * }\n * ```\n */\nexport function useBreadcrumbs(breadcrumbs: BreadcrumbItem[]): void {\n const setBreadcrumbs = useGlobalStore((state) => state.setBreadcrumbs);\n\n useEffect(() => {\n setBreadcrumbs(breadcrumbs);\n\n return () => {\n setBreadcrumbs(null);\n };\n }, [breadcrumbs, setBreadcrumbs]);\n}"],"mappings":"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","names":["useEffect","clsx","Button","Link","clsx","_a","styles","jsx","styles","jsx","jsxs","Fragment","jsx","jsxs","styles","Search","Fragment","jsx","jsxs","clsx","styles","Link","Button","clsx","styles","jsx","styles","jsx","jsxs","useEffect","clsx","styles","useEffect","useEffect"]}
|
|
1
|
+
{"version":3,"sources":["../src/components/RootLayout/RootLayout.tsx","../src/components/GlobalHeader/GlobalHeader.tsx","../src/components/Breadcrumbs/Breadcrumbs.tsx","../src/routes.ts","../src/store/globalState.ts","../src/locales/translations.ts","../src/hooks/use-layout-translation.ts","../src/components/MenuButton/MenuButton.tsx","../src/components/NavigationMenu/NavigationMenu.tsx","../src/navigationMenu.ts","../src/components/NavigationMenuItem/NavigationMenuItem.tsx","../src/components/GlobalFooter/GlobalFooter.tsx","../src/hooks/use-breadcrumbs.ts"],"sourcesContent":["'use client';\n\nimport { useEffect } from 'react';\nimport clsx from 'clsx';\nimport { GlobalHeader } from '../GlobalHeader';\nimport { GlobalFooter } from '../GlobalFooter';\nimport type { RootLayoutProps } from './RootLayout.types';\nimport styles from './RootLayout.module.css';\nimport { useGlobalStore } from '@/store/globalState';\nimport { SkipLink } from '@digdir/designsystemet-react';\nimport { useLayoutTranslation } from '@/hooks/use-layout-translation';\n\nexport function RootLayout({\n children,\n zone, \n className,\n}: RootLayoutProps) {\n const initialize = useGlobalStore((state) => state.initialize);\n const setZone = useGlobalStore((state) => state.setZone);\n const isMenuOpen = useGlobalStore((state) => state.isMenuOpen); \n const {t } = useLayoutTranslation();\n\n useEffect(() => {\n setZone(zone);\n }, [zone, setZone]);\n\n useEffect(() => {\n try {\n const maybe = initialize();\n if (maybe && typeof (maybe as Promise<void>).then === 'function') {\n (maybe as Promise<void>).catch((error) => {\n console.error('Failed to initialize global state:', error);\n });\n }\n } catch (error) {\n console.error('Failed to initialize global state:', error);\n }\n }, [initialize]);\n\n return (\n <div className={clsx(styles.root, isMenuOpen && styles.menuOpen, className)} data-zone={zone}>\n <SkipLink className={styles.skipLink} href='#main-content'>{t(\"common.skipLink\")}</SkipLink>\n <GlobalHeader zone={zone}/>\n <main id=\"main-content\" tabIndex={-1} className={styles.main}>{children}</main>\n <GlobalFooter />\n </div>\n );\n}","'use client';\n\nimport { Button, Link } from '@digdir/designsystemet-react';\nimport clsx from 'clsx';\nimport { Breadcrumbs } from '../Breadcrumbs';\nimport { MenuButton } from '../MenuButton';\nimport type { GlobalHeaderProps } from './GlobalHeader.types';\nimport styles from './GlobalHeader.module.css';\nimport { ALLOW_DARK_THEME, useGlobalStore } from '@/store/globalState';\nimport { Search } from 'lucide-react';\nimport { useLayoutTranslation } from '@/hooks/use-layout-translation';\n\nexport function GlobalHeader({ className, zone }: GlobalHeaderProps) {\n const isMenuOpen = useGlobalStore((state) => state.isMenuOpen);\n const setIsMenuOpen = useGlobalStore((state) => state.setIsMenuOpen);\n const setTheme = useGlobalStore((state) => state.setTheme);\n const theme = useGlobalStore((state) => state.theme);\n const { t } = useLayoutTranslation();\n \n // function for toggling darkmode lightmode with zustand store\n function toggleDarkMode() {\n setTheme(theme === 'dark' ? 'light' : 'dark');\n }\n\n\n return (\n <header className={clsx(styles.header, isMenuOpen && styles.menuOpen, className)}>\n <div className={styles.headerContainer}>\n <div className={styles.topBarContainer}>\n <Link href=\"https://www.statsbygg.no\">\n <img src={'https://dok.statsbygg.no/wp-content/uploads/2025/11/Statsbygg_logo.svg'} alt=\"Logo\" className={styles.logo} />\n </Link>\n <div className={styles.actionsContainer}>\n {!isMenuOpen && (\n <>\n {ALLOW_DARK_THEME && <Button onClick={toggleDarkMode} className={styles.themeToggleButton}>\n {theme === 'dark' ? '☀️' : '🌙'}\n </Button>}\n <Button\n variant=\"secondary\"\n onClick={() => setIsMenuOpen(true)}\n className={styles.searchButton}\n aria-label={t(\"common.search\")}\n >\n <Search size={20} aria-hidden=\"true\" />\n {t(\"common.search\")}\n </Button></>\n )}\n <MenuButton zone={zone} />\n </div>\n </div>\n <Breadcrumbs zone={zone} />\n </div>\n </header>\n );\n}","\"use client\";\n\nimport { usePathname } from \"next/navigation\";\nimport { Breadcrumbs } from \"@digdir/designsystemet-react\";\nimport clsx from \"clsx\";\nimport type { BreadcrumbsProps } from \"./Breadcrumbs.types\";\nimport styles from \"./Breadcrumbs.module.css\";\nimport { getBreadcrumbs, getZoneRoot, transformHrefForZone } from \"@/routes\";\nimport { useGlobalStore } from \"@/store/globalState\";\nimport { useLayoutTranslation } from \"@/hooks/use-layout-translation\";\n\nexport function SbBreadcrumbs({ className, zone }: BreadcrumbsProps) {\n const pathname = usePathname();\n const manualBreadcrumbs = useGlobalStore((state) => state.breadcrumbs);\n const isDev = process.env.NODE_ENV === \"development\";\n const prodUrl = \"https://www.statsbygg.no\";\n const zoneRoot = getZoneRoot(zone);\n const { t } = useLayoutTranslation();\n\n const fullPath =\n isDev && zoneRoot !== \"/\" && !pathname.startsWith(zoneRoot)\n ? `${zoneRoot}${pathname}`\n : pathname;\n\n const breadcrumbs = manualBreadcrumbs ?? getBreadcrumbs(zone, fullPath);\n\n if (breadcrumbs.length <= 1) {\n return null;\n }\n\n return (\n <Breadcrumbs\n aria-label={t(\"common.youAreHere\")}\n className={clsx(styles.breadcrumbs, className)}\n >\n <Breadcrumbs.List>\n {breadcrumbs.map((crumb, index) => {\n const isLast = index === breadcrumbs.length - 1;\n const href = manualBreadcrumbs\n ? crumb.href\n : transformHrefForZone(crumb.href, zone, { isDev, prodUrl });\n\n return (\n <Breadcrumbs.Item key={crumb.href}>\n <Breadcrumbs.Link\n href={href}\n aria-current={isLast ? \"page\" : undefined}\n className={isLast ? styles.currentLink : styles.link}\n >\n {crumb.label}\n </Breadcrumbs.Link>\n </Breadcrumbs.Item>\n );\n })}\n </Breadcrumbs.List>\n </Breadcrumbs>\n );\n}\n","export type RouteNodeInput =\n | { segment: string; label: string; children?: RouteNodeInput[] }\n | { path: string; label: string; children?: RouteNodeInput[] };\n\nexport type RouteNode = {\n path: string;\n label: string;\n children?: RouteNode[];\n};\n\nexport type RouteDefinition = {\n path: string;\n label: string;\n zone: string;\n};\n\nconst ZONE_TREES_INPUT: Record<string, RouteNodeInput> = {\n sbno: {\n segment: '',// primary root route, no breadcrumb\n label: 'Hjem',\n children: [\n { segment: 'nyheter', label: 'Nyheter' },\n ],\n },\n lokaler: {\n segment: 'lokaler',\n label: 'Statens eide og leide lokaler',\n children: [\n {\n segment: 'lokalbruk', label: 'Lokalbruk'\n },\n { segment: 'veiledning', label: 'Veiledning' },\n { segment: 'statlige-eiendommer', label: 'Statlige eiendommer' },\n { segment: 'ledig-for-fremleie', label: 'Ledig for fremleie' },\n { segment: 'statistikk', label: 'Statistikk' },\n ],\n },\n};\n\n\ntype Key = `${string}:${string}`; // `${zone}:${absolutePath}`\n\nconst ROUTES_INDEX: Record<string, RouteDefinition[]> = {};\nconst PARENT_INDEX = new Map<Key, Key | null>(); // child -> parent\nconst ZONE_TREES: Record<string, RouteNode> = {}; // normalized absolute trees\n\nfunction isSegmentNode(n: RouteNodeInput): n is Extract<RouteNodeInput, { segment: string }> {\n return (n as any).segment !== undefined && (n as any).path === undefined;\n}\nfunction isPathNode(n: RouteNodeInput): n is Extract<RouteNodeInput, { path: string }> {\n return (n as any).path !== undefined;\n}\n\nfunction joinPath(base: string, seg: string): string {\n if (!base) return seg ? `/${seg}` : '/';\n return seg ? `${base.replace(/\\/+$/, '')}/${seg.replace(/^\\/+/, '')}` : base || '/';\n}\n\nfunction normalizeToAbsolute(node: RouteNodeInput, base = ''): RouteNode {\n const path = isSegmentNode(node)\n ? joinPath(base, node.segment)\n : isPathNode(node)\n ? (node.path === '' ? '/' : node.path)\n : '/';\n\n const children = (node.children ?? []).map((c) => normalizeToAbsolute(c, path));\n return { path, label: (node as any).label, children: children.length ? children : undefined };\n}\n\n(function buildAll() {\n // Normalize each zone tree to absolute paths\n Object.keys(ZONE_TREES_INPUT).forEach((zone) => {\n ZONE_TREES[zone] = normalizeToAbsolute(ZONE_TREES_INPUT[zone]);\n });\n\n // Build flat indexes + parent relationships\n function walk(zone: string, node: RouteNode, parentKey: Key | null) {\n const def: RouteDefinition = { zone, path: node.path, label: node.label };\n const key: Key = `${zone}:${node.path}`;\n ROUTES_INDEX[zone].push(def);\n PARENT_INDEX.set(key, parentKey);\n for (const child of node.children ?? []) {\n walk(zone, child, key);\n }\n }\n\n (Object.keys(ZONE_TREES) as string[]).forEach((zone) => {\n ROUTES_INDEX[zone] = [];\n walk(zone, ZONE_TREES[zone], null);\n });\n})();\n\n\nfunction findBestMatch(zone: string, pathname: string): RouteDefinition | undefined {\n const list = ROUTES_INDEX[zone] ?? [];\n let best: RouteDefinition | undefined;\n\n for (const r of list) {\n if (pathname === r.path) {\n best = r; // exact wins\n break;\n }\n if (pathname.startsWith(r.path.endsWith('/') ? r.path : r.path + '/')) {\n if (!best || r.path.length > best.path.length) best = r;\n }\n }\n // fallback: zone root\n return best ?? list.find((r) => r.path === ZONE_TREES[zone]?.path);\n}\n\nexport function getZoneRoutes(zone: string): RouteDefinition[] {\n return ROUTES_INDEX[zone] ?? [];\n}\n\n// Top-level links for a zone’s menu (children of the zone root)\nexport function getZoneMenuRoutes(zone: string): RouteDefinition[] {\n const root = ZONE_TREES[zone];\n const children = root?.children ?? [];\n return children.map((c) => ({ zone, path: c.path, label: c.label }));\n}\n\nexport function getAllZones(): string[] {\n return Object.keys(ZONE_TREES);\n}\n\nexport function getZoneRoot(zone: string): string {\n return ZONE_TREES[zone]?.path || '/';\n}\n\n// prettify dynamic slug labels\nfunction labelFromSlug(slug: string): string {\n try {\n const s = decodeURIComponent(slug).replace(/[-_]+/g, ' ').trim();\n return s ? s.charAt(0).toUpperCase() + s.slice(1) : slug;\n } catch {\n return slug;\n }\n}\n\nexport function getBreadcrumbs(\n zone: string,\n pathname: string\n): Array<{ label: string; href: string }> {\n\n const normalizedPathname = pathname === '/' ? pathname : pathname.replace(/\\/+$/, '');\n\n // sbno root has no crumbs\n if (zone === 'sbno' && normalizedPathname === '/') return [];\n\n const match = findBestMatch(zone, normalizedPathname);\n if (!match) return [];\n\n const chain: RouteDefinition[] = [];\n let key: Key | undefined = `${zone}:${match.path}`;\n while (key) {\n const parentKey = PARENT_INDEX.get(key);\n const [z, p] = key.split(':') as [string, string];\n const def = (ROUTES_INDEX[z] ?? []).find((r) => r.path === p);\n if (def) chain.unshift(def);\n key = parentKey ?? undefined;\n }\n\n const homeRoute = (ROUTES_INDEX.sbno ?? []).find((r) => r.path === '/');\n if (\n homeRoute &&\n !(chain.length === 1 && chain[0].zone === 'sbno' && chain[0].path === '/') &&\n (chain.length === 0 || chain[0].path !== homeRoute.path)\n ) {\n chain.unshift(homeRoute);\n }\n\n // If the pathname is deeper than the best static match, add a dynamic tail\n const last = chain[chain.length - 1];\n if (last && normalizedPathname !== last.path && normalizedPathname.startsWith(last.path.endsWith('/') ? last.path : last.path + '/')) {\n const segments = normalizedPathname.split('/').filter(Boolean);\n const tail = segments[segments.length - 1];\n chain.push({ zone, path: normalizedPathname, label: labelFromSlug(tail) });\n }\n\n return chain.map((r) => ({ label: r.label, href: r.path }));\n}\n\nexport function transformHrefForZone(\n targetPath: string,\n currentZone: string,\n options: {\n isDev: boolean;\n prodUrl?: string;\n }\n): string {\n const { isDev, prodUrl } = options;\n\n const targetZone = getZoneFromPathname(targetPath);\n const isCrossZone = targetZone !== currentZone;\n\n if (isCrossZone && isDev && prodUrl) {\n return `${prodUrl}${targetPath}`;\n }\n\n const currentZoneRoot = getZoneRoot(currentZone);\n if (!isCrossZone && isDev && currentZoneRoot !== '/') {\n return targetPath.replace(currentZoneRoot, '') || '/';\n }\n\n return targetPath;\n}\n\nexport function getZoneFromPathname(pathname: string): string {\n if (pathname.startsWith('/lokaler')) return 'lokaler';\n return 'sbno';\n}\n\nexport function getZonePrefixBreadcrumbs(zone: string): Array<{ label: string; href: string }> {\n const zoneRoot = getZoneRoot(zone);\n return getBreadcrumbs(zone, zoneRoot);\n}","import { create, StateCreator } from 'zustand';\nimport { persist, createJSONStorage } from 'zustand/middleware';\n\nexport type Theme = 'light' | 'dark' | 'system';\n\nexport const ALLOW_DARK_THEME = false;\n\nexport type BreadcrumbItem = {\n label: string;\n href: string;\n};\n\nexport type GlobalState = {\n user?: { id: string; name?: string } | null;\n theme: Theme;\n locale: string;\n isMenuOpen: boolean;\n zone: string | null;\n breadcrumbs: BreadcrumbItem[] | null;\n setUser: (user: GlobalState['user']) => void;\n setTheme: (theme: Theme) => void;\n setLocale: (locale: string) => void;\n setIsMenuOpen: (isOpen: boolean) => void;\n toggleMenu: () => void;\n setZone: (zone: string) => void;\n setBreadcrumbs: (breadcrumbs: BreadcrumbItem[] | null) => void;\n initialize: () => void | Promise<void>;\n};\n\nconst creator: StateCreator<GlobalState, [['zustand/persist', unknown]]> = (set, get) => ({\n user: null,\n theme: 'light',\n locale: 'no',\n isMenuOpen: false,\n zone: null,\n breadcrumbs: null,\n setUser: (user) => set({ user }),\n setTheme: (theme) => {\n set({ theme: ALLOW_DARK_THEME ? theme : 'light' });\n if (typeof document !== 'undefined' && ALLOW_DARK_THEME) {\n document.documentElement.setAttribute('data-color-scheme', theme);\n }\n },\n setLocale: (locale) => set({ locale }),\n setIsMenuOpen: (isMenuOpen) => set({ isMenuOpen }),\n toggleMenu: () => set((state) => ({ isMenuOpen: !state.isMenuOpen })),\n setZone: (zone) => set({ zone }),\n setBreadcrumbs: (breadcrumbs) => set({ breadcrumbs }),\n initialize: () => {\n if (typeof document !== 'undefined' && ALLOW_DARK_THEME) {\n document.documentElement.setAttribute('data-color-scheme', get().theme);\n }\n },\n});\n\nexport const useGlobalStore = create<GlobalState>()(\n persist(creator, {\n name: 'statsbygg-global-state',\n storage: createJSONStorage(() => localStorage),\n partialize: (state) => ({\n user: state.user,\n theme: ALLOW_DARK_THEME ? state.theme : 'light',\n locale: state.locale,\n }),\n })\n);","export const translations = {\n no: {\n 'common.menu': 'Meny',\n 'common.close': 'Lukk',\n 'common.search': 'Søk',\n 'common.searchLabel': 'Søk',\n 'common.youAreHere': 'Du er her:',\n 'common.skipLink': 'Hopp til hovedinnhold',\n 'common.home': 'Hjem',\n 'footer.content': 'Statsbygg Footer',\n 'menu.helpTitle': 'Hva kan vi hjelpe deg med?',\n 'menu.mainMenuLabel': 'Hovedmeny',\n 'menu.closeMenu': 'Lukk meny',\n 'menu.openMenu': 'Åpne meny',\n }\n};\n\nexport type TranslationKey = keyof typeof translations.no;","import { TranslationKey, translations } from '@/locales/translations';\nimport { useGlobalStore } from '@/store/globalState';\n\nexport function useLayoutTranslation() {\n const locale = useGlobalStore((state) => state.locale) as keyof typeof translations;\n \n const languageMap = translations[locale] || translations.no;\n\n function t(key: TranslationKey): string {\n return languageMap[key] || key;\n }\n\n return { t, locale };\n}","\"use client\";\n\nimport { Button } from \"@digdir/designsystemet-react\";\nimport { Menu, X } from \"lucide-react\";\nimport { useGlobalStore } from \"@/store/globalState\";\nimport { NavigationMenu } from \"../NavigationMenu\";\nimport type { MenuButtonProps } from \"./MenuButton.types\";\nimport { useLayoutTranslation } from \"@/hooks/use-layout-translation\";\n\nexport function MenuButton({ zone }: MenuButtonProps) {\n const isMenuOpen = useGlobalStore((state) => state.isMenuOpen);\n const toggleMenu = useGlobalStore((state) => state.toggleMenu);\n const { t } = useLayoutTranslation();\n\n return (\n <>\n <Button\n variant=\"primary\"\n onClick={toggleMenu}\n aria-expanded={isMenuOpen}\n aria-label={isMenuOpen ? t(\"menu.closeMenu\") : t(\"menu.openMenu\")}\n >\n {isMenuOpen ? (\n <X size={20} aria-hidden=\"true\" />\n ) : (\n <Menu size={20} aria-hidden=\"true\" />\n )}\n {isMenuOpen ? t(\"common.close\") : t(\"common.menu\")}\n </Button>\n <NavigationMenu zone={zone} />\n </>\n );\n}\n","\"use client\";\nimport { useState, useEffect, useRef } from \"react\";\nimport { Heading, Search, Textfield } from \"@digdir/designsystemet-react\";\nimport { NAVIGATION_MENU } from \"../../navigationMenu\";\nimport { NavigationMenuItem } from \"../NavigationMenuItem/NavigationMenuItem\";\nimport { useGlobalStore } from \"../../store/globalState\";\nimport styles from \"./NavigationMenu.module.css\";\nimport { MenuSection, NavigationMenuProps } from \"./NavigationMenu.types\";\nimport { useLayoutTranslation } from \"@/hooks/use-layout-translation\";\n\nexport function NavigationMenu({ zone }: NavigationMenuProps) {\n const [searchValue, setSearchValue] = useState(\"\");\n const isMenuOpen = useGlobalStore((state) => state.isMenuOpen);\n const setIsMenuOpen = useGlobalStore((state) => state.setIsMenuOpen);\n const searchInputRef = useRef<HTMLInputElement>(null);\n\n const { t } = useLayoutTranslation();\n\n useEffect(() => {\n if (!isMenuOpen) return;\n\n const handleEscape = (event: KeyboardEvent) => {\n if (event.key === \"Escape\") {\n setIsMenuOpen(false);\n }\n };\n\n setTimeout(() => {\n searchInputRef.current?.focus();\n }, 100);\n\n document.addEventListener(\"keydown\", handleEscape);\n\n return () => {\n document.removeEventListener(\"keydown\", handleEscape);\n };\n }, [setIsMenuOpen, isMenuOpen]);\n\n function handleBackdropClick(e: React.MouseEvent<HTMLDivElement>) {\n if (e.target === e.currentTarget) {\n setIsMenuOpen(false);\n }\n }\n\n return (\n <>\n {isMenuOpen && (\n <div className={styles.backdrop} onClick={handleBackdropClick} />\n )}\n <div\n className={`${styles.menuOverlay} ${!isMenuOpen ? styles.hidden : \"\"}`}\n >\n <div className={styles.container}>\n <div className={styles.searchSection}>\n <Heading level={1}>{t(\"menu.helpTitle\")}</Heading>\n <Search>\n <Search.Input\n aria-label={t(\"common.search\")}\n ref={searchInputRef}\n value={searchValue}\n onChange={(e) => setSearchValue(e.target.value)}\n placeholder={t(\"common.search\")}\n className={styles.searchField}\n />\n <Search.Clear />\n </Search>\n </div>\n\n <nav\n className={styles.menuSections}\n aria-label={t(\"menu.mainMenuLabel\")}\n >\n {NAVIGATION_MENU.map(\n (section: MenuSection, sectionIndex: number) => (\n <section\n key={sectionIndex}\n className={styles.section}\n style={{ animationDelay: `${0.15 + sectionIndex * 0.06}s` }}\n >\n {/* Only show section header for non-subsection layouts */}\n {section.layout !== \"subsections\" && (\n <Heading level={2} className={styles.sectionHeader}>\n {section.title}\n </Heading>\n )}\n\n {section.layout === \"subsections\" && section.subsections ? (\n <div className={styles.subsectionsGrid}>\n {section.subsections.map(\n (subsection, subsectionIndex) => (\n <div\n key={subsectionIndex}\n className={styles.subsection}\n >\n <Heading\n level={2}\n className={styles.subsectionHeader}\n >\n {subsection.title}\n </Heading>\n <div className={styles.subsectionItems}>\n {subsection.items.map((item, itemIndex) => (\n <NavigationMenuItem\n key={itemIndex}\n item={item}\n animationDelay={\n 150 +\n sectionIndex * 60 +\n subsectionIndex * 40 +\n itemIndex * 25\n }\n compact\n />\n ))}\n </div>\n </div>\n )\n )}\n </div>\n ) : (\n <div\n className={\n sectionIndex === 2\n ? styles.itemsGridThreeCol\n : styles.itemsGrid\n }\n >\n {section.items?.map((item, itemIndex) => (\n <NavigationMenuItem\n key={itemIndex}\n item={item}\n animationDelay={\n 150 + sectionIndex * 60 + itemIndex * 25\n }\n />\n ))}\n </div>\n )}\n </section>\n )\n )}\n </nav>\n </div>\n </div>\n </>\n );\n}\n","export interface MenuItem {\n label: string;\n href: string;\n external?: boolean;\n children?: MenuItem[];\n}\n\nexport interface MenuSubsection {\n title: string;\n items: MenuItem[];\n}\n\nexport interface MenuSection {\n title: string;\n layout?: 'columns' | 'subsections';\n items?: MenuItem[];\n subsections?: MenuSubsection[];\n}\n\nexport const NAVIGATION_MENU: MenuSection[] = [\n {\n title: 'Våre tjenester',\n layout: 'columns',\n items: [\n {\n label: 'Statens eide og leide lokaler',\n href: '/lokaler',\n children: [\n { label: 'Lokalbruk', href: '/lokaler/lokalbruk' },\n { label: 'Statlige eiendommer', href: '/lokaler/statlige-eiendommer' },\n { label: 'Ledig for fremleie', href: '/lokaler/ledig-for-fremleie' },\n { label: 'Statistikk for lokalbruk', href: '/lokaler/statistikk' },\n { label: 'Veiledning', href: '/lokaler/veiledning' },\n ],\n },\n {\n label: 'For leietakere',\n href: '/for-leietakere',\n children: [\n { label: 'Leieveileder', href: '/leietakere/leieveileder' },\n { label: 'Lenke til underside', href: '/leietakere/lenke1' },\n { label: 'Lenke til underside', href: '/leietakere/lenke2' },\n ],\n },\n {\n label: 'For byggebransjen',\n href: '/byggebransjen',\n children: [\n { label: 'Våre krav', href: '/byggebransjen/vare-krav' },\n { label: 'BIM', href: '/byggebransjen/bim' },\n { label: 'ByggBoks', href: '/byggebransjen/byggboks' },\n { label: 'Lenke til underside', href: '/byggebransjen/lenke' },\n ],\n },\n {\n label: 'Karriere',\n href: '/karriere',\n children: [\n { label: 'Ledige stillinger', href: '/karriere/ledige-stillinger' },\n { label: 'Å jobbe hos oss', href: '/karriere/jobbe-hos-oss' },\n { label: 'Møt en statsbygger', href: '/karriere/mot-en-statsbygger' },\n { label: 'Summer internship', href: '/karriere/summer-internship' },\n { label: 'Studenter og lærlinger', href: '/karriere/studenter-og-laerlinger' },\n ],\n },\n ],\n },\n {\n title: 'Informasjon om statsbygg',\n layout: 'subsections',\n subsections: [\n {\n title: 'Informasjon om statsbygg',\n items: [\n { label: 'Om Statsbygg', href: '/om-statsbygg' },\n { label: 'Samfunnsansvar', href: '/samfunnsansvar' },\n { label: 'Tilgjengelighet', href: '/tilgjengelighet' },\n { label: 'About Statsbygg', href: '/about-statsbygg' },\n { label: 'Statsbygg birra', href: '/statsbygg-birra' },\n ],\n },\n {\n title: 'Kontakt oss',\n items: [\n { label: 'Kontakt oss', href: '/kontakt' },\n { label: 'Ansattsøk', href: '/ansattsok' },\n { label: 'For pressen', href: '/for-pressen' },\n { label: 'Varsling', href: '/varsling' },\n ],\n },\n {\n title: 'Arkiv',\n items: [\n { label: 'Nyheter', href: '/nyheter' },\n { label: 'Artikler om bygg', href: '/artikler-om-bygg' },\n { label: 'Dokumenter', href: '/dokumenter' },\n ],\n },\n ],\n },\n {\n title: 'Eksterne lenker',\n layout: 'columns',\n items: [\n {\n label: 'Statens lokaler',\n href: 'https://statensinnleie.no',\n external: true,\n },\n {\n label: 'Statens innleie',\n href: 'https://statensinnleie.no',\n external: true,\n },\n {\n label: 'MainManager FM',\n href: 'https://mainmanager.no',\n external: true,\n },\n {\n label: 'Offentlig postjournal',\n href: 'https://postjournal.no',\n external: true,\n },\n {\n label: 'SIMBA (BIM)',\n href: 'https://bim.statsbygg.no',\n external: true,\n },\n ],\n },\n];","import { Link, List } from '@digdir/designsystemet-react';\nimport { ExternalLink } from 'lucide-react';\nimport { MenuItem } from '../../navigationMenu';\nimport styles from './NavigationMenuItem.module.css';\nimport { NavigationMenuItemProps } from './NavigationMenuItem.types';\n\nexport function NavigationMenuItem({ item, animationDelay, compact = false }: NavigationMenuItemProps) {\n if (compact) {\n return (\n <div\n className={styles.itemColumn}\n style={{ animationDelay: `${animationDelay}ms` }}\n >\n <Link\n href={item.href}\n className={styles.compactLink}\n target={item.external ? '_blank' : undefined}\n rel={item.external ? 'noopener noreferrer' : undefined}\n >\n {item.label}\n {item.external && (\n <ExternalLink size={16} aria-hidden=\"true\" />\n )}\n </Link>\n </div>\n );\n }\n\n return (\n <div\n className={styles.itemColumn}\n style={{ animationDelay: `${animationDelay}ms` }}\n >\n <Link\n href={item.href}\n className={styles.parentLink}\n target={item.external ? '_blank' : undefined}\n rel={item.external ? 'noopener noreferrer' : undefined}\n >\n {item.label}\n {item.external && (\n <ExternalLink size={20} aria-hidden=\"true\" />\n )}\n </Link>\n\n {item.children && item.children.length > 0 && (\n <List.Unordered className={styles.childItems}>\n {item.children.map((child, childIndex) => (\n <List.Item\n key={childIndex}\n className={styles.childItem}\n style={{ animationDelay: `${animationDelay + 30 + (childIndex * 15)}ms` }}\n >\n <Link\n href={child.href}\n className={styles.childLink}\n target={child.external ? '_blank' : undefined}\n rel={child.external ? 'noopener noreferrer' : undefined}\n >\n {child.label}\n {child.external && (\n <ExternalLink size={20} aria-hidden=\"true\" />\n )}\n </Link>\n </List.Item>\n ))}\n </List.Unordered>\n )}\n </div>\n );\n}","'use client';\n\nimport { Paragraph } from '@digdir/designsystemet-react';\nimport clsx from 'clsx';\nimport type { GlobalFooterProps } from './GlobalFooter.types';\nimport styles from './GlobalFooter.module.css';\nimport { useLayoutTranslation } from '@/hooks/use-layout-translation';\n\nexport function GlobalFooter({ className }: GlobalFooterProps) {\n const { t } = useLayoutTranslation();\n\n return (\n <footer className={clsx(styles.footer, className)}>\n <div className={styles.container}>\n <div className={styles.content}>\n <Paragraph>\n {t('footer.content')}\n </Paragraph>\n\n\n </div>\n </div>\n </footer>\n );\n}","import { useEffect, useRef } from 'react';\nimport { useGlobalStore, BreadcrumbItem } from '../store/globalState';\nimport { getZonePrefixBreadcrumbs } from '../routes';\n\nexport function useBreadcrumbs(breadcrumbs: BreadcrumbItem[]): void {\n const setBreadcrumbs = useGlobalStore((state) => state.setBreadcrumbs);\n const zone = useGlobalStore((state) => state.zone);\n const breadcrumbsStringified = JSON.stringify(breadcrumbs);\n const hasSetBreadcrumbs = useRef(false);\n\n useEffect(() => {\n if (!zone || hasSetBreadcrumbs.current) return;\n\n const zonePrefixBreadcrumbs = getZonePrefixBreadcrumbs(zone);\n const parsedBreadcrumbs = JSON.parse(breadcrumbsStringified) as BreadcrumbItem[];\n const fullBreadcrumbs = [...zonePrefixBreadcrumbs, ...parsedBreadcrumbs];\n \n setBreadcrumbs(fullBreadcrumbs);\n hasSetBreadcrumbs.current = true;\n\n return () => {\n setBreadcrumbs(null);\n hasSetBreadcrumbs.current = false;\n };\n }, [zone, breadcrumbsStringified, setBreadcrumbs]);\n}"],"mappings":";;;AAEA,SAAS,aAAAA,kBAAiB;AAC1B,OAAOC,WAAU;;;ACDjB,SAAS,UAAAC,SAAQ,QAAAC,aAAY;AAC7B,OAAOC,WAAU;;;ACDjB,SAAS,mBAAmB;AAC5B,SAAS,mBAAmB;AAC5B,OAAO,UAAU;AAEjB,OAAO,YAAY;;;ACUnB,IAAM,mBAAmD;AAAA,EACvD,MAAM;AAAA,IACJ,SAAS;AAAA;AAAA,IACT,OAAO;AAAA,IACP,UAAU;AAAA,MACR,EAAE,SAAS,WAAW,OAAO,UAAU;AAAA,IACzC;AAAA,EACF;AAAA,EACA,SAAS;AAAA,IACP,SAAS;AAAA,IACT,OAAO;AAAA,IACP,UAAU;AAAA,MACR;AAAA,QACE,SAAS;AAAA,QAAa,OAAO;AAAA,MAC/B;AAAA,MACA,EAAE,SAAS,cAAc,OAAO,aAAa;AAAA,MAC7C,EAAE,SAAS,uBAAuB,OAAO,sBAAsB;AAAA,MAC/D,EAAE,SAAS,sBAAsB,OAAO,qBAAqB;AAAA,MAC7D,EAAE,SAAS,cAAc,OAAO,aAAa;AAAA,IAC/C;AAAA,EACF;AACF;AAKA,IAAM,eAAkD,CAAC;AACzD,IAAM,eAAe,oBAAI,IAAqB;AAC9C,IAAM,aAAwC,CAAC;AAE/C,SAAS,cAAc,GAAsE;AAC3F,SAAQ,EAAU,YAAY,UAAc,EAAU,SAAS;AACjE;AACA,SAAS,WAAW,GAAmE;AACrF,SAAQ,EAAU,SAAS;AAC7B;AAEA,SAAS,SAAS,MAAc,KAAqB;AACnD,MAAI,CAAC,KAAM,QAAO,MAAM,IAAI,GAAG,KAAK;AACpC,SAAO,MAAM,GAAG,KAAK,QAAQ,QAAQ,EAAE,CAAC,IAAI,IAAI,QAAQ,QAAQ,EAAE,CAAC,KAAK,QAAQ;AAClF;AAEA,SAAS,oBAAoB,MAAsB,OAAO,IAAe;AA1DzE;AA2DE,QAAM,OAAO,cAAc,IAAI,IAC3B,SAAS,MAAM,KAAK,OAAO,IAC3B,WAAW,IAAI,IACZ,KAAK,SAAS,KAAK,MAAM,KAAK,OAC/B;AAEN,QAAM,aAAY,UAAK,aAAL,YAAiB,CAAC,GAAG,IAAI,CAAC,MAAM,oBAAoB,GAAG,IAAI,CAAC;AAC9E,SAAO,EAAE,MAAM,OAAQ,KAAa,OAAO,UAAU,SAAS,SAAS,WAAW,OAAU;AAC9F;AAAA,CAEC,SAAS,WAAW;AAEnB,SAAO,KAAK,gBAAgB,EAAE,QAAQ,CAAC,SAAS;AAC9C,eAAW,IAAI,IAAI,oBAAoB,iBAAiB,IAAI,CAAC;AAAA,EAC/D,CAAC;AAGD,WAAS,KAAK,MAAc,MAAiB,WAAuB;AA5EtE;AA6EI,UAAM,MAAuB,EAAE,MAAM,MAAM,KAAK,MAAM,OAAO,KAAK,MAAM;AACxE,UAAM,MAAW,GAAG,IAAI,IAAI,KAAK,IAAI;AACrC,iBAAa,IAAI,EAAE,KAAK,GAAG;AAC3B,iBAAa,IAAI,KAAK,SAAS;AAC/B,eAAW,UAAS,UAAK,aAAL,YAAiB,CAAC,GAAG;AACvC,WAAK,MAAM,OAAO,GAAG;AAAA,IACvB;AAAA,EACF;AAEA,EAAC,OAAO,KAAK,UAAU,EAAe,QAAQ,CAAC,SAAS;AACtD,iBAAa,IAAI,IAAI,CAAC;AACtB,SAAK,MAAM,WAAW,IAAI,GAAG,IAAI;AAAA,EACnC,CAAC;AACH,GAAG;AAGH,SAAS,cAAc,MAAc,UAA+C;AA7FpF;AA8FE,QAAM,QAAO,kBAAa,IAAI,MAAjB,YAAsB,CAAC;AACpC,MAAI;AAEJ,aAAW,KAAK,MAAM;AACpB,QAAI,aAAa,EAAE,MAAM;AACvB,aAAO;AACP;AAAA,IACF;AACA,QAAI,SAAS,WAAW,EAAE,KAAK,SAAS,GAAG,IAAI,EAAE,OAAO,EAAE,OAAO,GAAG,GAAG;AACrE,UAAI,CAAC,QAAQ,EAAE,KAAK,SAAS,KAAK,KAAK,OAAQ,QAAO;AAAA,IACxD;AAAA,EACF;AAEA,SAAO,sBAAQ,KAAK,KAAK,CAAC,MAAG;AA3G/B,QAAAC;AA2GkC,aAAE,WAASA,MAAA,WAAW,IAAI,MAAf,gBAAAA,IAAkB;AAAA,GAAI;AACnE;AAiBO,SAAS,YAAY,MAAsB;AA7HlD;AA8HE,WAAO,gBAAW,IAAI,MAAf,mBAAkB,SAAQ;AACnC;AAGA,SAAS,cAAc,MAAsB;AAC3C,MAAI;AACF,UAAM,IAAI,mBAAmB,IAAI,EAAE,QAAQ,UAAU,GAAG,EAAE,KAAK;AAC/D,WAAO,IAAI,EAAE,OAAO,CAAC,EAAE,YAAY,IAAI,EAAE,MAAM,CAAC,IAAI;AAAA,EACtD,SAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEO,SAAS,eACd,MACA,UACwC;AA9I1C;AAgJE,QAAM,qBAAqB,aAAa,MAAM,WAAW,SAAS,QAAQ,QAAQ,EAAE;AAGpF,MAAI,SAAS,UAAU,uBAAuB,IAAK,QAAO,CAAC;AAE3D,QAAM,QAAQ,cAAc,MAAM,kBAAkB;AACpD,MAAI,CAAC,MAAO,QAAO,CAAC;AAEpB,QAAM,QAA2B,CAAC;AAClC,MAAI,MAAuB,GAAG,IAAI,IAAI,MAAM,IAAI;AAChD,SAAO,KAAK;AACV,UAAM,YAAY,aAAa,IAAI,GAAG;AACtC,UAAM,CAAC,GAAG,CAAC,IAAI,IAAI,MAAM,GAAG;AAC5B,UAAM,QAAO,kBAAa,CAAC,MAAd,YAAmB,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,SAAS,CAAC;AAC5D,QAAI,IAAK,OAAM,QAAQ,GAAG;AAC1B,UAAM,gCAAa;AAAA,EACrB;AAEA,QAAM,cAAa,kBAAa,SAAb,YAAqB,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,SAAS,GAAG;AACtE,MACE,aACA,EAAE,MAAM,WAAW,KAAK,MAAM,CAAC,EAAE,SAAS,UAAU,MAAM,CAAC,EAAE,SAAS,SACrE,MAAM,WAAW,KAAK,MAAM,CAAC,EAAE,SAAS,UAAU,OACnD;AACA,UAAM,QAAQ,SAAS;AAAA,EACzB;AAGA,QAAM,OAAO,MAAM,MAAM,SAAS,CAAC;AACnC,MAAI,QAAQ,uBAAuB,KAAK,QAAQ,mBAAmB,WAAW,KAAK,KAAK,SAAS,GAAG,IAAI,KAAK,OAAO,KAAK,OAAO,GAAG,GAAG;AACpI,UAAM,WAAW,mBAAmB,MAAM,GAAG,EAAE,OAAO,OAAO;AAC7D,UAAM,OAAO,SAAS,SAAS,SAAS,CAAC;AACzC,UAAM,KAAK,EAAE,MAAM,MAAM,oBAAoB,OAAO,cAAc,IAAI,EAAE,CAAC;AAAA,EAC3E;AAEA,SAAO,MAAM,IAAI,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,MAAM,EAAE,KAAK,EAAE;AAC5D;AAEO,SAAS,qBACd,YACA,aACA,SAIQ;AACR,QAAM,EAAE,OAAO,QAAQ,IAAI;AAE3B,QAAM,aAAa,oBAAoB,UAAU;AACjD,QAAM,cAAc,eAAe;AAEnC,MAAI,eAAe,SAAS,SAAS;AACnC,WAAO,GAAG,OAAO,GAAG,UAAU;AAAA,EAChC;AAEA,QAAM,kBAAkB,YAAY,WAAW;AAC/C,MAAI,CAAC,eAAe,SAAS,oBAAoB,KAAK;AACpD,WAAO,WAAW,QAAQ,iBAAiB,EAAE,KAAK;AAAA,EACpD;AAEA,SAAO;AACT;AAEO,SAAS,oBAAoB,UAA0B;AAC5D,MAAI,SAAS,WAAW,UAAU,EAAG,QAAO;AAC5C,SAAO;AACT;AAEO,SAAS,yBAAyB,MAAsD;AAC7F,QAAM,WAAW,YAAY,IAAI;AACjC,SAAO,eAAe,MAAM,QAAQ;AACtC;;;ACvNA,SAAS,cAA4B;AACrC,SAAS,SAAS,yBAAyB;AAIpC,IAAM,mBAAmB;AAwBhC,IAAM,UAAqE,CAAC,KAAK,SAAS;AAAA,EACxF,MAAM;AAAA,EACN,OAAO;AAAA,EACP,QAAQ;AAAA,EACR,YAAY;AAAA,EACZ,MAAM;AAAA,EACN,aAAa;AAAA,EACb,SAAS,CAAC,SAAS,IAAI,EAAE,KAAK,CAAC;AAAA,EAC/B,UAAU,CAAC,UAAU;AACnB,QAAI,EAAE,OAAO,mBAAmB,QAAQ,QAAQ,CAAC;AACjD,QAAI,OAAO,aAAa,eAAe,kBAAkB;AACvD,eAAS,gBAAgB,aAAa,qBAAqB,KAAK;AAAA,IAClE;AAAA,EACF;AAAA,EACA,WAAW,CAAC,WAAW,IAAI,EAAE,OAAO,CAAC;AAAA,EACrC,eAAe,CAAC,eAAe,IAAI,EAAE,WAAW,CAAC;AAAA,EACjD,YAAY,MAAM,IAAI,CAAC,WAAW,EAAE,YAAY,CAAC,MAAM,WAAW,EAAE;AAAA,EACpE,SAAS,CAAC,SAAS,IAAI,EAAE,KAAK,CAAC;AAAA,EAC/B,gBAAgB,CAAC,gBAAgB,IAAI,EAAE,YAAY,CAAC;AAAA,EACpD,YAAY,MAAM;AAChB,QAAI,OAAO,aAAa,eAAe,kBAAkB;AACvD,eAAS,gBAAgB,aAAa,qBAAqB,IAAI,EAAE,KAAK;AAAA,IACxE;AAAA,EACF;AACF;AAEO,IAAM,iBAAiB,OAAoB;AAAA,EAChD,QAAQ,SAAS;AAAA,IACf,MAAM;AAAA,IACN,SAAS,kBAAkB,MAAM,YAAY;AAAA,IAC7C,YAAY,CAAC,WAAW;AAAA,MACtB,MAAM,MAAM;AAAA,MACZ,OAAO,mBAAmB,MAAM,QAAQ;AAAA,MACxC,QAAQ,MAAM;AAAA,IAChB;AAAA,EACF,CAAC;AACH;;;ACjEO,IAAM,eAAe;AAAA,EAC1B,IAAI;AAAA,IACF,eAAe;AAAA,IACf,gBAAgB;AAAA,IAChB,iBAAiB;AAAA,IACjB,sBAAsB;AAAA,IACtB,qBAAqB;AAAA,IACrB,mBAAmB;AAAA,IACnB,eAAe;AAAA,IACf,kBAAkB;AAAA,IAClB,kBAAkB;AAAA,IAClB,sBAAsB;AAAA,IACtB,kBAAkB;AAAA,IAClB,iBAAiB;AAAA,EACnB;AACF;;;ACZO,SAAS,uBAAuB;AACrC,QAAM,SAAS,eAAe,CAAC,UAAU,MAAM,MAAM;AAErD,QAAM,cAAc,aAAa,MAAM,KAAK,aAAa;AAEzD,WAAS,EAAE,KAA6B;AACtC,WAAO,YAAY,GAAG,KAAK;AAAA,EAC7B;AAEA,SAAO,EAAE,GAAG,OAAO;AACrB;;;AJ+Bc;AAjCP,SAAS,cAAc,EAAE,WAAW,KAAK,GAAqB;AACnE,QAAM,WAAW,YAAY;AAC7B,QAAM,oBAAoB,eAAe,CAAC,UAAU,MAAM,WAAW;AACrE,QAAM,QAAQ,QAAQ,IAAI,aAAa;AACvC,QAAM,UAAU;AAChB,QAAM,WAAW,YAAY,IAAI;AACjC,QAAM,EAAE,EAAE,IAAI,qBAAqB;AAEnC,QAAM,WACJ,SAAS,aAAa,OAAO,CAAC,SAAS,WAAW,QAAQ,IACtD,GAAG,QAAQ,GAAG,QAAQ,KACtB;AAEN,QAAM,cAAc,gDAAqB,eAAe,MAAM,QAAQ;AAEtE,MAAI,YAAY,UAAU,GAAG;AAC3B,WAAO;AAAA,EACT;AAEA,SACE;AAAA,IAAC;AAAA;AAAA,MACC,cAAY,EAAE,mBAAmB;AAAA,MACjC,WAAW,KAAK,OAAO,aAAa,SAAS;AAAA,MAE7C,8BAAC,YAAY,MAAZ,EACE,sBAAY,IAAI,CAAC,OAAO,UAAU;AACjC,cAAM,SAAS,UAAU,YAAY,SAAS;AAC9C,cAAM,OAAO,oBACT,MAAM,OACN,qBAAqB,MAAM,MAAM,MAAM,EAAE,OAAO,QAAQ,CAAC;AAE7D,eACE,oBAAC,YAAY,MAAZ,EACC;AAAA,UAAC,YAAY;AAAA,UAAZ;AAAA,YACC;AAAA,YACA,gBAAc,SAAS,SAAS;AAAA,YAChC,WAAW,SAAS,OAAO,cAAc,OAAO;AAAA,YAE/C,gBAAM;AAAA;AAAA,QACT,KAPqB,MAAM,IAQ7B;AAAA,MAEJ,CAAC,GACH;AAAA;AAAA,EACF;AAEJ;;;AKvDA,SAAS,cAAc;AACvB,SAAS,MAAM,SAAS;;;ACFxB,SAAS,UAAU,WAAW,cAAc;AAC5C,SAAS,SAAS,cAAyB;;;ACiBpC,IAAM,kBAAiC;AAAA,EAC5C;AAAA,IACE,OAAO;AAAA,IACP,QAAQ;AAAA,IACR,OAAO;AAAA,MACL;AAAA,QACE,OAAO;AAAA,QACP,MAAM;AAAA,QACN,UAAU;AAAA,UACR,EAAE,OAAO,aAAa,MAAM,qBAAqB;AAAA,UACjD,EAAE,OAAO,uBAAuB,MAAM,+BAA+B;AAAA,UACrE,EAAE,OAAO,sBAAsB,MAAM,8BAA8B;AAAA,UACnE,EAAE,OAAO,4BAA4B,MAAM,sBAAsB;AAAA,UACjE,EAAE,OAAO,cAAc,MAAM,sBAAsB;AAAA,QACrD;AAAA,MACF;AAAA,MACA;AAAA,QACE,OAAO;AAAA,QACP,MAAM;AAAA,QACN,UAAU;AAAA,UACR,EAAE,OAAO,gBAAgB,MAAM,2BAA2B;AAAA,UAC1D,EAAE,OAAO,uBAAuB,MAAM,qBAAqB;AAAA,UAC3D,EAAE,OAAO,uBAAuB,MAAM,qBAAqB;AAAA,QAC7D;AAAA,MACF;AAAA,MACA;AAAA,QACE,OAAO;AAAA,QACP,MAAM;AAAA,QACN,UAAU;AAAA,UACR,EAAE,OAAO,gBAAa,MAAM,2BAA2B;AAAA,UACvD,EAAE,OAAO,OAAO,MAAM,qBAAqB;AAAA,UAC3C,EAAE,OAAO,YAAY,MAAM,0BAA0B;AAAA,UACrD,EAAE,OAAO,uBAAuB,MAAM,uBAAuB;AAAA,QAC/D;AAAA,MACF;AAAA,MACA;AAAA,QACE,OAAO;AAAA,QACP,MAAM;AAAA,QACN,UAAU;AAAA,UACR,EAAE,OAAO,qBAAqB,MAAM,8BAA8B;AAAA,UAClE,EAAE,OAAO,sBAAmB,MAAM,0BAA0B;AAAA,UAC5D,EAAE,OAAO,yBAAsB,MAAM,+BAA+B;AAAA,UACpE,EAAE,OAAO,qBAAqB,MAAM,8BAA8B;AAAA,UAClE,EAAE,OAAO,6BAA0B,MAAM,oCAAoC;AAAA,QAC/E;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA,EACA;AAAA,IACE,OAAO;AAAA,IACP,QAAQ;AAAA,IACR,aAAa;AAAA,MACX;AAAA,QACE,OAAO;AAAA,QACP,OAAO;AAAA,UACL,EAAE,OAAO,gBAAgB,MAAM,gBAAgB;AAAA,UAC/C,EAAE,OAAO,kBAAkB,MAAM,kBAAkB;AAAA,UACnD,EAAE,OAAO,mBAAmB,MAAM,mBAAmB;AAAA,UACrD,EAAE,OAAO,mBAAmB,MAAM,mBAAmB;AAAA,UACrD,EAAE,OAAO,mBAAmB,MAAM,mBAAmB;AAAA,QACvD;AAAA,MACF;AAAA,MACA;AAAA,QACE,OAAO;AAAA,QACP,OAAO;AAAA,UACL,EAAE,OAAO,eAAe,MAAM,WAAW;AAAA,UACzC,EAAE,OAAO,gBAAa,MAAM,aAAa;AAAA,UACzC,EAAE,OAAO,eAAe,MAAM,eAAe;AAAA,UAC7C,EAAE,OAAO,YAAY,MAAM,YAAY;AAAA,QACzC;AAAA,MACF;AAAA,MACA;AAAA,QACE,OAAO;AAAA,QACP,OAAO;AAAA,UACL,EAAE,OAAO,WAAW,MAAM,WAAW;AAAA,UACrC,EAAE,OAAO,oBAAoB,MAAM,oBAAoB;AAAA,UACvD,EAAE,OAAO,cAAc,MAAM,cAAc;AAAA,QAC7C;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA,EACA;AAAA,IACE,OAAO;AAAA,IACP,QAAQ;AAAA,IACR,OAAO;AAAA,MACL;AAAA,QACE,OAAO;AAAA,QACP,MAAM;AAAA,QACN,UAAU;AAAA,MACZ;AAAA,MACA;AAAA,QACE,OAAO;AAAA,QACP,MAAM;AAAA,QACN,UAAU;AAAA,MACZ;AAAA,MACA;AAAA,QACE,OAAO;AAAA,QACP,MAAM;AAAA,QACN,UAAU;AAAA,MACZ;AAAA,MACA;AAAA,QACE,OAAO;AAAA,QACP,MAAM;AAAA,QACN,UAAU;AAAA,MACZ;AAAA,MACA;AAAA,QACE,OAAO;AAAA,QACP,MAAM;AAAA,QACN,UAAU;AAAA,MACZ;AAAA,IACF;AAAA,EACF;AACF;;;ACnIA,SAAS,MAAM,YAAY;AAC3B,SAAS,oBAAoB;AAE7B,OAAOC,aAAY;AAUX,SAQI,OAAAC,MARJ;AAPD,SAAS,mBAAmB,EAAE,MAAM,gBAAgB,UAAU,MAAM,GAA4B;AACrG,MAAI,SAAS;AACX,WACE,gBAAAA;AAAA,MAAC;AAAA;AAAA,QACC,WAAWD,QAAO;AAAA,QAClB,OAAO,EAAE,gBAAgB,GAAG,cAAc,KAAK;AAAA,QAE/C;AAAA,UAAC;AAAA;AAAA,YACC,MAAM,KAAK;AAAA,YACX,WAAWA,QAAO;AAAA,YAClB,QAAQ,KAAK,WAAW,WAAW;AAAA,YACnC,KAAK,KAAK,WAAW,wBAAwB;AAAA,YAE5C;AAAA,mBAAK;AAAA,cACL,KAAK,YACJ,gBAAAC,KAAC,gBAAa,MAAM,IAAI,eAAY,QAAO;AAAA;AAAA;AAAA,QAE/C;AAAA;AAAA,IACF;AAAA,EAEJ;AAEA,SACE;AAAA,IAAC;AAAA;AAAA,MACC,WAAWD,QAAO;AAAA,MAClB,OAAO,EAAE,gBAAgB,GAAG,cAAc,KAAK;AAAA,MAE/C;AAAA;AAAA,UAAC;AAAA;AAAA,YACC,MAAM,KAAK;AAAA,YACX,WAAWA,QAAO;AAAA,YAClB,QAAQ,KAAK,WAAW,WAAW;AAAA,YACnC,KAAK,KAAK,WAAW,wBAAwB;AAAA,YAE5C;AAAA,mBAAK;AAAA,cACL,KAAK,YACJ,gBAAAC,KAAC,gBAAa,MAAM,IAAI,eAAY,QAAO;AAAA;AAAA;AAAA,QAE/C;AAAA,QAEC,KAAK,YAAY,KAAK,SAAS,SAAS,KACvC,gBAAAA,KAAC,KAAK,WAAL,EAAe,WAAWD,QAAO,YAC/B,eAAK,SAAS,IAAI,CAAC,OAAO,eACzB,gBAAAC;AAAA,UAAC,KAAK;AAAA,UAAL;AAAA,YAEC,WAAWD,QAAO;AAAA,YAClB,OAAO,EAAE,gBAAgB,GAAG,iBAAiB,KAAM,aAAa,EAAG,KAAK;AAAA,YAExE;AAAA,cAAC;AAAA;AAAA,gBACC,MAAM,MAAM;AAAA,gBACZ,WAAWA,QAAO;AAAA,gBAClB,QAAQ,MAAM,WAAW,WAAW;AAAA,gBACpC,KAAK,MAAM,WAAW,wBAAwB;AAAA,gBAE7C;AAAA,wBAAM;AAAA,kBACN,MAAM,YACL,gBAAAC,KAAC,gBAAa,MAAM,IAAI,eAAY,QAAO;AAAA;AAAA;AAAA,YAE/C;AAAA;AAAA,UAdK;AAAA,QAeP,CACD,GACH;AAAA;AAAA;AAAA,EAEJ;AAEJ;;;AFhEA,OAAOC,aAAY;AAuCf,mBAEI,OAAAC,MAQI,QAAAC,aAVR;AAnCG,SAAS,eAAe,EAAE,KAAK,GAAwB;AAC5D,QAAM,CAAC,aAAa,cAAc,IAAI,SAAS,EAAE;AACjD,QAAM,aAAa,eAAe,CAAC,UAAU,MAAM,UAAU;AAC7D,QAAM,gBAAgB,eAAe,CAAC,UAAU,MAAM,aAAa;AACnE,QAAM,iBAAiB,OAAyB,IAAI;AAEpD,QAAM,EAAE,EAAE,IAAI,qBAAqB;AAEnC,YAAU,MAAM;AACd,QAAI,CAAC,WAAY;AAEjB,UAAM,eAAe,CAAC,UAAyB;AAC7C,UAAI,MAAM,QAAQ,UAAU;AAC1B,sBAAc,KAAK;AAAA,MACrB;AAAA,IACF;AAEA,eAAW,MAAM;AA3BrB;AA4BM,2BAAe,YAAf,mBAAwB;AAAA,IAC1B,GAAG,GAAG;AAEN,aAAS,iBAAiB,WAAW,YAAY;AAEjD,WAAO,MAAM;AACX,eAAS,oBAAoB,WAAW,YAAY;AAAA,IACtD;AAAA,EACF,GAAG,CAAC,eAAe,UAAU,CAAC;AAE9B,WAAS,oBAAoB,GAAqC;AAChE,QAAI,EAAE,WAAW,EAAE,eAAe;AAChC,oBAAc,KAAK;AAAA,IACrB;AAAA,EACF;AAEA,SACE,gBAAAA,MAAA,YACG;AAAA,kBACC,gBAAAD,KAAC,SAAI,WAAWE,QAAO,UAAU,SAAS,qBAAqB;AAAA,IAEjE,gBAAAF;AAAA,MAAC;AAAA;AAAA,QACC,WAAW,GAAGE,QAAO,WAAW,IAAI,CAAC,aAAaA,QAAO,SAAS,EAAE;AAAA,QAEpE,0BAAAD,MAAC,SAAI,WAAWC,QAAO,WACrB;AAAA,0BAAAD,MAAC,SAAI,WAAWC,QAAO,eACrB;AAAA,4BAAAF,KAAC,WAAQ,OAAO,GAAI,YAAE,gBAAgB,GAAE;AAAA,YACxC,gBAAAC,MAAC,UACC;AAAA,8BAAAD;AAAA,gBAAC,OAAO;AAAA,gBAAP;AAAA,kBACC,cAAY,EAAE,eAAe;AAAA,kBAC7B,KAAK;AAAA,kBACL,OAAO;AAAA,kBACP,UAAU,CAAC,MAAM,eAAe,EAAE,OAAO,KAAK;AAAA,kBAC9C,aAAa,EAAE,eAAe;AAAA,kBAC9B,WAAWE,QAAO;AAAA;AAAA,cACpB;AAAA,cACA,gBAAAF,KAAC,OAAO,OAAP,EAAa;AAAA,eAChB;AAAA,aACF;AAAA,UAEA,gBAAAA;AAAA,YAAC;AAAA;AAAA,cACC,WAAWE,QAAO;AAAA,cAClB,cAAY,EAAE,oBAAoB;AAAA,cAEjC,0BAAgB;AAAA,gBACf,CAAC,SAAsB,iBAAsB;AAzE3D;AA0EgB,yCAAAD;AAAA,oBAAC;AAAA;AAAA,sBAEC,WAAWC,QAAO;AAAA,sBAClB,OAAO,EAAE,gBAAgB,GAAG,OAAO,eAAe,IAAI,IAAI;AAAA,sBAGzD;AAAA,gCAAQ,WAAW,iBAClB,gBAAAF,KAAC,WAAQ,OAAO,GAAG,WAAWE,QAAO,eAClC,kBAAQ,OACX;AAAA,wBAGD,QAAQ,WAAW,iBAAiB,QAAQ,cAC3C,gBAAAF,KAAC,SAAI,WAAWE,QAAO,iBACpB,kBAAQ,YAAY;AAAA,0BACnB,CAAC,YAAY,oBACX,gBAAAD;AAAA,4BAAC;AAAA;AAAA,8BAEC,WAAWC,QAAO;AAAA,8BAElB;AAAA,gDAAAF;AAAA,kCAAC;AAAA;AAAA,oCACC,OAAO;AAAA,oCACP,WAAWE,QAAO;AAAA,oCAEjB,qBAAW;AAAA;AAAA,gCACd;AAAA,gCACA,gBAAAF,KAAC,SAAI,WAAWE,QAAO,iBACpB,qBAAW,MAAM,IAAI,CAAC,MAAM,cAC3B,gBAAAF;AAAA,kCAAC;AAAA;AAAA,oCAEC;AAAA,oCACA,gBACE,MACA,eAAe,KACf,kBAAkB,KAClB,YAAY;AAAA,oCAEd,SAAO;AAAA;AAAA,kCARF;AAAA,gCASP,CACD,GACH;AAAA;AAAA;AAAA,4BAvBK;AAAA,0BAwBP;AAAA,wBAEJ,GACF,IAEA,gBAAAA;AAAA,0BAAC;AAAA;AAAA,4BACC,WACE,iBAAiB,IACbE,QAAO,oBACPA,QAAO;AAAA,4BAGZ,wBAAQ,UAAR,mBAAe,IAAI,CAAC,MAAM,cACzB,gBAAAF;AAAA,8BAAC;AAAA;AAAA,gCAEC;AAAA,gCACA,gBACE,MAAM,eAAe,KAAK,YAAY;AAAA;AAAA,8BAHnC;AAAA,4BAKP;AAAA;AAAA,wBAEJ;AAAA;AAAA;AAAA,oBA7DG;AAAA,kBA+DP;AAAA;AAAA,cAEJ;AAAA;AAAA,UACF;AAAA,WACF;AAAA;AAAA,IACF;AAAA,KACF;AAEJ;;;ADnII,qBAAAG,WAQM,OAAAC,MAPJ,QAAAC,aADF;AANG,SAAS,WAAW,EAAE,KAAK,GAAoB;AACpD,QAAM,aAAa,eAAe,CAAC,UAAU,MAAM,UAAU;AAC7D,QAAM,aAAa,eAAe,CAAC,UAAU,MAAM,UAAU;AAC7D,QAAM,EAAE,EAAE,IAAI,qBAAqB;AAEnC,SACE,gBAAAA,MAAAF,WAAA,EACE;AAAA,oBAAAE;AAAA,MAAC;AAAA;AAAA,QACC,SAAQ;AAAA,QACR,SAAS;AAAA,QACT,iBAAe;AAAA,QACf,cAAY,aAAa,EAAE,gBAAgB,IAAI,EAAE,eAAe;AAAA,QAE/D;AAAA,uBACC,gBAAAD,KAAC,KAAE,MAAM,IAAI,eAAY,QAAO,IAEhC,gBAAAA,KAAC,QAAK,MAAM,IAAI,eAAY,QAAO;AAAA,UAEpC,aAAa,EAAE,cAAc,IAAI,EAAE,aAAa;AAAA;AAAA;AAAA,IACnD;AAAA,IACA,gBAAAA,KAAC,kBAAe,MAAY;AAAA,KAC9B;AAEJ;;;ANzBA,OAAOE,aAAY;AAEnB,SAAS,UAAAC,eAAc;AAqBX,SAIE,YAAAC,WAJF,OAAAC,MAQE,QAAAC,aARF;AAlBL,SAAS,aAAa,EAAE,WAAW,KAAK,GAAsB;AACnE,QAAM,aAAa,eAAe,CAAC,UAAU,MAAM,UAAU;AAC7D,QAAM,gBAAgB,eAAe,CAAC,UAAU,MAAM,aAAa;AACnE,QAAM,WAAW,eAAe,CAAC,UAAU,MAAM,QAAQ;AACzD,QAAM,QAAQ,eAAe,CAAC,UAAU,MAAM,KAAK;AACnD,QAAM,EAAE,EAAE,IAAI,qBAAqB;AAGnC,WAAS,iBAAiB;AACxB,aAAS,UAAU,SAAU,UAAU,MAAM;AAAA,EAC/C;AAGA,SACE,gBAAAD,KAAC,YAAO,WAAWE,MAAKC,QAAO,QAAQ,cAAcA,QAAO,UAAU,SAAS,GAC7E,0BAAAF,MAAC,SAAI,WAAWE,QAAO,iBACrB;AAAA,oBAAAF,MAAC,SAAI,WAAWE,QAAO,iBACrB;AAAA,sBAAAH,KAACI,OAAA,EAAK,MAAK,4BACT,0BAAAJ,KAAC,SAAI,KAAK,0EAA0E,KAAI,QAAO,WAAWG,QAAO,MAAM,GACzH;AAAA,MACA,gBAAAF,MAAC,SAAI,WAAWE,QAAO,kBACpB;AAAA,SAAC,cACA,gBAAAF,MAAAF,WAAA,EACC;AAAA,8BAAoB,gBAAAC,KAACK,SAAA,EAAO,SAAS,gBAAgB,WAAWF,QAAO,mBACrE,oBAAU,SAAS,iBAAO,aAC7B;AAAA,UACA,gBAAAF;AAAA,YAACI;AAAA,YAAA;AAAA,cACC,SAAQ;AAAA,cACR,SAAS,MAAM,cAAc,IAAI;AAAA,cACjC,WAAWF,QAAO;AAAA,cAClB,cAAY,EAAE,eAAe;AAAA,cAE7B;AAAA,gCAAAH,KAACM,SAAA,EAAO,MAAM,IAAI,eAAY,QAAO;AAAA,gBACpC,EAAE,eAAe;AAAA;AAAA;AAAA,UACpB;AAAA,WAAS;AAAA,QAEX,gBAAAN,KAAC,cAAW,MAAY;AAAA,SAC1B;AAAA,OACF;AAAA,IACA,gBAAAA,KAAC,iBAAY,MAAY;AAAA,KAC3B,GACF;AAEJ;;;AUrDA,SAAS,iBAAiB;AAC1B,OAAOO,WAAU;AAEjB,OAAOC,aAAY;AAUT,gBAAAC,YAAA;AAPH,SAAS,aAAa,EAAE,UAAU,GAAsB;AAC7D,QAAM,EAAE,EAAE,IAAI,qBAAqB;AAEnC,SACE,gBAAAA,KAAC,YAAO,WAAWC,MAAKC,QAAO,QAAQ,SAAS,GAC9C,0BAAAF,KAAC,SAAI,WAAWE,QAAO,WACrB,0BAAAF,KAAC,SAAI,WAAWE,QAAO,SACrB,0BAAAF,KAAC,aACE,YAAE,gBAAgB,GACrB,GAGF,GACF,GACF;AAEJ;;;AXjBA,OAAOG,aAAY;AAEnB,SAAS,gBAAgB;AA+BrB,SACE,OAAAC,MADF,QAAAC,aAAA;AA5BG,SAAS,WAAW;AAAA,EACzB;AAAA,EACA;AAAA,EACA;AACF,GAAoB;AAClB,QAAM,aAAa,eAAe,CAAC,UAAU,MAAM,UAAU;AAC7D,QAAM,UAAU,eAAe,CAAC,UAAU,MAAM,OAAO;AACvD,QAAM,aAAa,eAAe,CAAC,UAAU,MAAM,UAAU;AAC7D,QAAM,EAAC,EAAE,IAAI,qBAAqB;AAElC,EAAAC,WAAU,MAAM;AACd,YAAQ,IAAI;AAAA,EACd,GAAG,CAAC,MAAM,OAAO,CAAC;AAElB,EAAAA,WAAU,MAAM;AACd,QAAI;AACF,YAAM,QAAQ,WAAW;AACzB,UAAI,SAAS,OAAQ,MAAwB,SAAS,YAAY;AAChE,QAAC,MAAwB,MAAM,CAAC,UAAU;AACxC,kBAAQ,MAAM,sCAAsC,KAAK;AAAA,QAC3D,CAAC;AAAA,MACH;AAAA,IACF,SAAS,OAAO;AACd,cAAQ,MAAM,sCAAsC,KAAK;AAAA,IAC3D;AAAA,EACF,GAAG,CAAC,UAAU,CAAC;AAEf,SACE,gBAAAD,MAAC,SAAI,WAAWE,MAAKC,QAAO,MAAM,cAAcA,QAAO,UAAU,SAAS,GAAG,aAAW,MACtF;AAAA,oBAAAJ,KAAC,YAAS,WAAWI,QAAO,UAAU,MAAK,iBAAiB,YAAE,iBAAiB,GAAE;AAAA,IACjF,gBAAAJ,KAAC,gBAAa,MAAW;AAAA,IACzB,gBAAAA,KAAC,UAAK,IAAG,gBAAe,UAAU,IAAI,WAAWI,QAAO,MAAO,UAAS;AAAA,IACxE,gBAAAJ,KAAC,gBAAa;AAAA,KAChB;AAEJ;;;AY/CA,SAAS,aAAAK,YAAW,UAAAC,eAAc;AAI3B,SAAS,eAAe,aAAqC;AAClE,QAAM,iBAAiB,eAAe,CAAC,UAAU,MAAM,cAAc;AACrE,QAAM,OAAO,eAAe,CAAC,UAAU,MAAM,IAAI;AACjD,QAAM,yBAAyB,KAAK,UAAU,WAAW;AACzD,QAAM,oBAAoBC,QAAO,KAAK;AAEtC,EAAAC,WAAU,MAAM;AACd,QAAI,CAAC,QAAQ,kBAAkB,QAAS;AAExC,UAAM,wBAAwB,yBAAyB,IAAI;AAC3D,UAAM,oBAAoB,KAAK,MAAM,sBAAsB;AAC3D,UAAM,kBAAkB,CAAC,GAAG,uBAAuB,GAAG,iBAAiB;AAEvE,mBAAe,eAAe;AAC9B,sBAAkB,UAAU;AAE5B,WAAO,MAAM;AACX,qBAAe,IAAI;AACnB,wBAAkB,UAAU;AAAA,IAC9B;AAAA,EACF,GAAG,CAAC,MAAM,wBAAwB,cAAc,CAAC;AACnD;","names":["useEffect","clsx","Button","Link","clsx","_a","styles","jsx","styles","jsx","jsxs","styles","Fragment","jsx","jsxs","styles","Search","Fragment","jsx","jsxs","clsx","styles","Link","Button","Search","clsx","styles","jsx","clsx","styles","styles","jsx","jsxs","useEffect","clsx","styles","useEffect","useRef","useRef","useEffect"]}
|