@statsbygg/layout 0.1.13 → 0.1.14
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.js +65 -49
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/dist/SmartLink.module.css +0 -3
package/dist/index.js
CHANGED
|
@@ -6,7 +6,7 @@ import clsx5 from "clsx";
|
|
|
6
6
|
import { SkipLink } from "@digdir/designsystemet-react";
|
|
7
7
|
|
|
8
8
|
// src/components/GlobalHeader/GlobalHeader.tsx
|
|
9
|
-
import { Button as Button2, Link as
|
|
9
|
+
import { Button as Button2, Link as Link3 } from "@digdir/designsystemet-react";
|
|
10
10
|
import { Search as Search2 } from "lucide-react";
|
|
11
11
|
import clsx3 from "clsx";
|
|
12
12
|
|
|
@@ -178,10 +178,26 @@ function useLayoutTranslation() {
|
|
|
178
178
|
return { t, locale };
|
|
179
179
|
}
|
|
180
180
|
|
|
181
|
+
// src/components/BreadcrumbLink/BreadcrumbLink.tsx
|
|
182
|
+
import Link from "next/link";
|
|
183
|
+
import { jsx } from "react/jsx-runtime";
|
|
184
|
+
function BreadcrumbLink({
|
|
185
|
+
href,
|
|
186
|
+
className,
|
|
187
|
+
ariaCurrent,
|
|
188
|
+
children
|
|
189
|
+
}) {
|
|
190
|
+
const isExternal = href.startsWith("http://") || href.startsWith("https://");
|
|
191
|
+
if (isExternal) {
|
|
192
|
+
return /* @__PURE__ */ jsx("a", { href, className, "aria-current": ariaCurrent, children });
|
|
193
|
+
}
|
|
194
|
+
return /* @__PURE__ */ jsx(Link, { href, className, "aria-current": ariaCurrent, children });
|
|
195
|
+
}
|
|
196
|
+
|
|
181
197
|
// src/components/Breadcrumbs/Breadcrumbs.tsx
|
|
182
198
|
import styles from "./Breadcrumbs.module.css";
|
|
183
|
-
import { jsx } from "react/jsx-runtime";
|
|
184
|
-
function SbBreadcrumbs({ className, routes }) {
|
|
199
|
+
import { jsx as jsx2 } from "react/jsx-runtime";
|
|
200
|
+
function SbBreadcrumbs({ className, routes, appBasePath }) {
|
|
185
201
|
const pathname = usePathname();
|
|
186
202
|
const manualBreadcrumbs = useGlobalStore((state) => state.breadcrumbs);
|
|
187
203
|
const { t } = useLayoutTranslation();
|
|
@@ -201,18 +217,18 @@ function SbBreadcrumbs({ className, routes }) {
|
|
|
201
217
|
if (breadcrumbs.length === 0) {
|
|
202
218
|
return null;
|
|
203
219
|
}
|
|
204
|
-
return /* @__PURE__ */
|
|
220
|
+
return /* @__PURE__ */ jsx2(
|
|
205
221
|
Breadcrumbs,
|
|
206
222
|
{
|
|
207
223
|
"aria-label": t("common.youAreHere"),
|
|
208
224
|
className: clsx(styles.breadcrumbs, className),
|
|
209
|
-
children: /* @__PURE__ */
|
|
225
|
+
children: /* @__PURE__ */ jsx2(Breadcrumbs.List, { children: breadcrumbs.map((crumb, index) => {
|
|
210
226
|
const isLast = index === breadcrumbs.length - 1;
|
|
211
|
-
return /* @__PURE__ */
|
|
212
|
-
|
|
227
|
+
return /* @__PURE__ */ jsx2(Breadcrumbs.Item, { children: /* @__PURE__ */ jsx2(
|
|
228
|
+
BreadcrumbLink,
|
|
213
229
|
{
|
|
214
230
|
href: crumb.href,
|
|
215
|
-
|
|
231
|
+
ariaCurrent: isLast ? "page" : void 0,
|
|
216
232
|
className: isLast ? styles.currentLink : styles.link,
|
|
217
233
|
children: crumb.label
|
|
218
234
|
}
|
|
@@ -349,9 +365,9 @@ import { usePathname as usePathname2 } from "next/navigation";
|
|
|
349
365
|
import clsx2 from "clsx";
|
|
350
366
|
|
|
351
367
|
// src/components/SmartLink/SmartLink.tsx
|
|
352
|
-
import
|
|
368
|
+
import Link2 from "next/link";
|
|
353
369
|
import { Link as DsLink } from "@digdir/designsystemet-react";
|
|
354
|
-
import { jsx as
|
|
370
|
+
import { jsx as jsx3 } from "react/jsx-runtime";
|
|
355
371
|
function SmartLink({
|
|
356
372
|
href,
|
|
357
373
|
appBasePath,
|
|
@@ -362,7 +378,7 @@ function SmartLink({
|
|
|
362
378
|
const isExternalUrl = href.startsWith("http://") || href.startsWith("https://");
|
|
363
379
|
const isLocalRoute = appBasePath && !isExternalUrl && (href === appBasePath || href.startsWith(`${appBasePath}/`));
|
|
364
380
|
if (isExternalUrl || external) {
|
|
365
|
-
return /* @__PURE__ */
|
|
381
|
+
return /* @__PURE__ */ jsx3(
|
|
366
382
|
DsLink,
|
|
367
383
|
{
|
|
368
384
|
href,
|
|
@@ -375,14 +391,14 @@ function SmartLink({
|
|
|
375
391
|
}
|
|
376
392
|
if (isLocalRoute) {
|
|
377
393
|
const localHref = href.replace(appBasePath, "") || "/";
|
|
378
|
-
return /* @__PURE__ */
|
|
394
|
+
return /* @__PURE__ */ jsx3(Link2, { href: localHref, className, children });
|
|
379
395
|
}
|
|
380
|
-
return /* @__PURE__ */
|
|
396
|
+
return /* @__PURE__ */ jsx3(DsLink, { href, className, children });
|
|
381
397
|
}
|
|
382
398
|
|
|
383
399
|
// src/components/NavigationMenuItem/NavigationMenuItem.tsx
|
|
384
400
|
import styles2 from "./NavigationMenuItem.module.css";
|
|
385
|
-
import { jsx as
|
|
401
|
+
import { jsx as jsx4, jsxs } from "react/jsx-runtime";
|
|
386
402
|
function NavigationMenuItem({
|
|
387
403
|
item,
|
|
388
404
|
animationDelay,
|
|
@@ -396,7 +412,7 @@ function NavigationMenuItem({
|
|
|
396
412
|
};
|
|
397
413
|
const isParentActive = isActive(item.href);
|
|
398
414
|
if (compact) {
|
|
399
|
-
return /* @__PURE__ */
|
|
415
|
+
return /* @__PURE__ */ jsx4(
|
|
400
416
|
"div",
|
|
401
417
|
{
|
|
402
418
|
className: styles2.itemColumn,
|
|
@@ -410,7 +426,7 @@ function NavigationMenuItem({
|
|
|
410
426
|
className: clsx2(styles2.compactLink, isParentActive && styles2.active),
|
|
411
427
|
children: [
|
|
412
428
|
item.label,
|
|
413
|
-
item.external && /* @__PURE__ */
|
|
429
|
+
item.external && /* @__PURE__ */ jsx4(ExternalLink, { size: 16, "aria-hidden": "true" })
|
|
414
430
|
]
|
|
415
431
|
}
|
|
416
432
|
)
|
|
@@ -432,13 +448,13 @@ function NavigationMenuItem({
|
|
|
432
448
|
className: clsx2(styles2.parentLink, isParentActive && styles2.active),
|
|
433
449
|
children: [
|
|
434
450
|
item.label,
|
|
435
|
-
item.external && /* @__PURE__ */
|
|
451
|
+
item.external && /* @__PURE__ */ jsx4(ExternalLink, { size: 20, "aria-hidden": "true" })
|
|
436
452
|
]
|
|
437
453
|
}
|
|
438
454
|
),
|
|
439
|
-
item.children && item.children.length > 0 && /* @__PURE__ */
|
|
455
|
+
item.children && item.children.length > 0 && /* @__PURE__ */ jsx4(List.Unordered, { className: styles2.childItems, children: item.children.map((child, childIndex) => {
|
|
440
456
|
const isChildActive = isActive(child.href);
|
|
441
|
-
return /* @__PURE__ */
|
|
457
|
+
return /* @__PURE__ */ jsx4(
|
|
442
458
|
List.Item,
|
|
443
459
|
{
|
|
444
460
|
className: styles2.childItem,
|
|
@@ -452,7 +468,7 @@ function NavigationMenuItem({
|
|
|
452
468
|
className: clsx2(styles2.childLink, isChildActive && styles2.active),
|
|
453
469
|
children: [
|
|
454
470
|
child.label,
|
|
455
|
-
child.external && /* @__PURE__ */
|
|
471
|
+
child.external && /* @__PURE__ */ jsx4(ExternalLink, { size: 16, "aria-hidden": "true" })
|
|
456
472
|
]
|
|
457
473
|
}
|
|
458
474
|
)
|
|
@@ -467,7 +483,7 @@ function NavigationMenuItem({
|
|
|
467
483
|
|
|
468
484
|
// src/components/NavigationMenu/NavigationMenu.tsx
|
|
469
485
|
import styles3 from "./NavigationMenu.module.css";
|
|
470
|
-
import { Fragment, jsx as
|
|
486
|
+
import { Fragment, jsx as jsx5, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
471
487
|
function NavigationMenu({ className, appBasePath }) {
|
|
472
488
|
const [searchValue, setSearchValue] = useState("");
|
|
473
489
|
const isMenuOpen = useGlobalStore((state) => state.isMenuOpen);
|
|
@@ -494,12 +510,12 @@ function NavigationMenu({ className, appBasePath }) {
|
|
|
494
510
|
}
|
|
495
511
|
}
|
|
496
512
|
return /* @__PURE__ */ jsxs2(Fragment, { children: [
|
|
497
|
-
isMenuOpen && /* @__PURE__ */
|
|
498
|
-
/* @__PURE__ */
|
|
513
|
+
isMenuOpen && /* @__PURE__ */ jsx5("div", { className: styles3.backdrop, onClick: handleBackdropClick }),
|
|
514
|
+
/* @__PURE__ */ jsx5("div", { className: `${styles3.menuOverlay} ${!isMenuOpen ? styles3.hidden : ""} ${className != null ? className : ""}`, children: /* @__PURE__ */ jsxs2("div", { className: styles3.container, children: [
|
|
499
515
|
/* @__PURE__ */ jsxs2("div", { className: styles3.searchSection, children: [
|
|
500
|
-
/* @__PURE__ */
|
|
516
|
+
/* @__PURE__ */ jsx5(Heading, { level: 1, children: t("menu.helpTitle") }),
|
|
501
517
|
/* @__PURE__ */ jsxs2(Search, { children: [
|
|
502
|
-
/* @__PURE__ */
|
|
518
|
+
/* @__PURE__ */ jsx5(
|
|
503
519
|
Search.Input,
|
|
504
520
|
{
|
|
505
521
|
"aria-label": t("common.search"),
|
|
@@ -510,10 +526,10 @@ function NavigationMenu({ className, appBasePath }) {
|
|
|
510
526
|
className: styles3.searchField
|
|
511
527
|
}
|
|
512
528
|
),
|
|
513
|
-
/* @__PURE__ */
|
|
529
|
+
/* @__PURE__ */ jsx5(Search.Clear, {})
|
|
514
530
|
] })
|
|
515
531
|
] }),
|
|
516
|
-
/* @__PURE__ */
|
|
532
|
+
/* @__PURE__ */ jsx5("nav", { className: styles3.menuSections, "aria-label": t("menu.mainMenuLabel"), children: NAVIGATION_MENU.map((section, sectionIndex) => {
|
|
517
533
|
var _a;
|
|
518
534
|
return /* @__PURE__ */ jsxs2(
|
|
519
535
|
"section",
|
|
@@ -521,10 +537,10 @@ function NavigationMenu({ className, appBasePath }) {
|
|
|
521
537
|
className: styles3.section,
|
|
522
538
|
style: { animationDelay: `${0.15 + sectionIndex * 0.06}s` },
|
|
523
539
|
children: [
|
|
524
|
-
section.layout !== "subsections" && /* @__PURE__ */
|
|
525
|
-
section.layout === "subsections" && section.subsections ? /* @__PURE__ */
|
|
526
|
-
/* @__PURE__ */
|
|
527
|
-
/* @__PURE__ */
|
|
540
|
+
section.layout !== "subsections" && /* @__PURE__ */ jsx5(Heading, { level: 2, className: styles3.sectionHeader, children: section.title }),
|
|
541
|
+
section.layout === "subsections" && section.subsections ? /* @__PURE__ */ jsx5("div", { className: styles3.subsectionsGrid, children: section.subsections.map((subsection, subsectionIndex) => /* @__PURE__ */ jsxs2("div", { className: styles3.subsection, children: [
|
|
542
|
+
/* @__PURE__ */ jsx5(Heading, { level: 2, className: styles3.subsectionHeader, children: subsection.title }),
|
|
543
|
+
/* @__PURE__ */ jsx5("div", { className: styles3.subsectionItems, children: subsection.items.map((item, itemIndex) => /* @__PURE__ */ jsx5(
|
|
528
544
|
NavigationMenuItem,
|
|
529
545
|
{
|
|
530
546
|
item,
|
|
@@ -534,7 +550,7 @@ function NavigationMenu({ className, appBasePath }) {
|
|
|
534
550
|
},
|
|
535
551
|
itemIndex
|
|
536
552
|
)) })
|
|
537
|
-
] }, subsectionIndex)) }) : /* @__PURE__ */
|
|
553
|
+
] }, subsectionIndex)) }) : /* @__PURE__ */ jsx5("div", { className: sectionIndex === 2 ? styles3.itemsGridThreeCol : styles3.itemsGrid, children: (_a = section.items) == null ? void 0 : _a.map((item, itemIndex) => /* @__PURE__ */ jsx5(
|
|
538
554
|
NavigationMenuItem,
|
|
539
555
|
{
|
|
540
556
|
item,
|
|
@@ -553,7 +569,7 @@ function NavigationMenu({ className, appBasePath }) {
|
|
|
553
569
|
}
|
|
554
570
|
|
|
555
571
|
// src/components/MenuButton/MenuButton.tsx
|
|
556
|
-
import { Fragment as Fragment2, jsx as
|
|
572
|
+
import { Fragment as Fragment2, jsx as jsx6, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
557
573
|
function MenuButton({ className, appBasePath }) {
|
|
558
574
|
const isMenuOpen = useGlobalStore((state) => state.isMenuOpen);
|
|
559
575
|
const toggleMenu = useGlobalStore((state) => state.toggleMenu);
|
|
@@ -568,18 +584,18 @@ function MenuButton({ className, appBasePath }) {
|
|
|
568
584
|
"aria-label": isMenuOpen ? t("menu.closeMenu") : t("menu.openMenu"),
|
|
569
585
|
className,
|
|
570
586
|
children: [
|
|
571
|
-
isMenuOpen ? /* @__PURE__ */
|
|
587
|
+
isMenuOpen ? /* @__PURE__ */ jsx6(X, { size: 20, "aria-hidden": "true" }) : /* @__PURE__ */ jsx6(Menu, { size: 20, "aria-hidden": "true" }),
|
|
572
588
|
isMenuOpen ? t("common.close") : t("common.menu")
|
|
573
589
|
]
|
|
574
590
|
}
|
|
575
591
|
),
|
|
576
|
-
/* @__PURE__ */
|
|
592
|
+
/* @__PURE__ */ jsx6(NavigationMenu, { appBasePath })
|
|
577
593
|
] });
|
|
578
594
|
}
|
|
579
595
|
|
|
580
596
|
// src/components/GlobalHeader/GlobalHeader.tsx
|
|
581
597
|
import styles4 from "./GlobalHeader.module.css";
|
|
582
|
-
import { Fragment as Fragment3, jsx as
|
|
598
|
+
import { Fragment as Fragment3, jsx as jsx7, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
583
599
|
function GlobalHeader({ className, routes, appBasePath }) {
|
|
584
600
|
const isMenuOpen = useGlobalStore((state) => state.isMenuOpen);
|
|
585
601
|
const setIsMenuOpen = useGlobalStore((state) => state.setIsMenuOpen);
|
|
@@ -589,9 +605,9 @@ function GlobalHeader({ className, routes, appBasePath }) {
|
|
|
589
605
|
function toggleDarkMode() {
|
|
590
606
|
setTheme(theme === "dark" ? "light" : "dark");
|
|
591
607
|
}
|
|
592
|
-
return /* @__PURE__ */
|
|
608
|
+
return /* @__PURE__ */ jsx7("header", { className: clsx3(styles4.header, isMenuOpen && styles4.menuOpen, className), children: /* @__PURE__ */ jsxs4("div", { className: styles4.headerContainer, children: [
|
|
593
609
|
/* @__PURE__ */ jsxs4("div", { className: styles4.topBarContainer, children: [
|
|
594
|
-
/* @__PURE__ */
|
|
610
|
+
/* @__PURE__ */ jsx7(Link3, { href: "https://www.statsbygg.no", children: /* @__PURE__ */ jsx7(
|
|
595
611
|
"img",
|
|
596
612
|
{
|
|
597
613
|
src: "https://dok.statsbygg.no/wp-content/uploads/2025/11/Statsbygg_logo.svg",
|
|
@@ -601,7 +617,7 @@ function GlobalHeader({ className, routes, appBasePath }) {
|
|
|
601
617
|
) }),
|
|
602
618
|
/* @__PURE__ */ jsxs4("div", { className: styles4.actionsContainer, children: [
|
|
603
619
|
!isMenuOpen && /* @__PURE__ */ jsxs4(Fragment3, { children: [
|
|
604
|
-
ALLOW_DARK_THEME && /* @__PURE__ */
|
|
620
|
+
ALLOW_DARK_THEME && /* @__PURE__ */ jsx7(Button2, { onClick: toggleDarkMode, className: styles4.themeToggleButton, children: theme === "dark" ? "\u2600\uFE0F" : "\u{1F319}" }),
|
|
605
621
|
/* @__PURE__ */ jsxs4(
|
|
606
622
|
Button2,
|
|
607
623
|
{
|
|
@@ -610,16 +626,16 @@ function GlobalHeader({ className, routes, appBasePath }) {
|
|
|
610
626
|
className: styles4.searchButton,
|
|
611
627
|
"aria-label": t("common.search"),
|
|
612
628
|
children: [
|
|
613
|
-
/* @__PURE__ */
|
|
629
|
+
/* @__PURE__ */ jsx7(Search2, { size: 20, "aria-hidden": "true" }),
|
|
614
630
|
t("common.search")
|
|
615
631
|
]
|
|
616
632
|
}
|
|
617
633
|
)
|
|
618
634
|
] }),
|
|
619
|
-
/* @__PURE__ */
|
|
635
|
+
/* @__PURE__ */ jsx7(MenuButton, { appBasePath })
|
|
620
636
|
] })
|
|
621
637
|
] }),
|
|
622
|
-
/* @__PURE__ */
|
|
638
|
+
/* @__PURE__ */ jsx7(SbBreadcrumbs, { routes, appBasePath })
|
|
623
639
|
] }) });
|
|
624
640
|
}
|
|
625
641
|
|
|
@@ -627,15 +643,15 @@ function GlobalHeader({ className, routes, appBasePath }) {
|
|
|
627
643
|
import { Paragraph } from "@digdir/designsystemet-react";
|
|
628
644
|
import clsx4 from "clsx";
|
|
629
645
|
import styles5 from "./GlobalFooter.module.css";
|
|
630
|
-
import { jsx as
|
|
646
|
+
import { jsx as jsx8 } from "react/jsx-runtime";
|
|
631
647
|
function GlobalFooter({ className }) {
|
|
632
648
|
const { t } = useLayoutTranslation();
|
|
633
|
-
return /* @__PURE__ */
|
|
649
|
+
return /* @__PURE__ */ jsx8("footer", { className: clsx4(styles5.footer, className), children: /* @__PURE__ */ jsx8("div", { className: styles5.container, children: /* @__PURE__ */ jsx8("div", { className: styles5.content, children: /* @__PURE__ */ jsx8(Paragraph, { children: t("footer.content") }) }) }) });
|
|
634
650
|
}
|
|
635
651
|
|
|
636
652
|
// src/components/RootLayout/RootLayout.tsx
|
|
637
653
|
import styles6 from "./RootLayout.module.css";
|
|
638
|
-
import { jsx as
|
|
654
|
+
import { jsx as jsx9, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
639
655
|
function RootLayout({ children, routes, appBasePath, className }) {
|
|
640
656
|
const initialize = useGlobalStore((state) => state.initialize);
|
|
641
657
|
const isMenuOpen = useGlobalStore((state) => state.isMenuOpen);
|
|
@@ -644,10 +660,10 @@ function RootLayout({ children, routes, appBasePath, className }) {
|
|
|
644
660
|
initialize();
|
|
645
661
|
}, [initialize]);
|
|
646
662
|
return /* @__PURE__ */ jsxs5("div", { className: clsx5(styles6.root, isMenuOpen && styles6.menuOpen, className), children: [
|
|
647
|
-
/* @__PURE__ */
|
|
648
|
-
/* @__PURE__ */
|
|
649
|
-
/* @__PURE__ */
|
|
650
|
-
/* @__PURE__ */
|
|
663
|
+
/* @__PURE__ */ jsx9(SkipLink, { className: styles6.skipLink, href: "#main-content", children: t("common.skipLink") }),
|
|
664
|
+
/* @__PURE__ */ jsx9(GlobalHeader, { routes, appBasePath }),
|
|
665
|
+
/* @__PURE__ */ jsx9("main", { id: "main-content", tabIndex: -1, className: styles6.main, children }),
|
|
666
|
+
/* @__PURE__ */ jsx9(GlobalFooter, {})
|
|
651
667
|
] });
|
|
652
668
|
}
|
|
653
669
|
|
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/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/SmartLink/SmartLink.tsx","../src/components/GlobalFooter/GlobalFooter.tsx","../src/hooks/use-breadcrumbs.ts"],"sourcesContent":["'use client';\n\nimport { useEffect } from 'react';\nimport clsx from 'clsx';\nimport { SkipLink } from '@digdir/designsystemet-react';\nimport { GlobalHeader } from '../GlobalHeader';\nimport { GlobalFooter } from '../GlobalFooter';\nimport { useGlobalStore } from '@/store/globalState';\nimport { useLayoutTranslation } from '@/hooks/use-layout-translation';\nimport type { RootLayoutProps } from './RootLayout.types';\nimport styles from './RootLayout.module.css';\n\nexport function RootLayout({ children, routes, appBasePath, className }: RootLayoutProps) {\n const initialize = useGlobalStore((state) => state.initialize);\n const isMenuOpen = useGlobalStore((state) => state.isMenuOpen);\n const { t } = useLayoutTranslation();\n\n useEffect(() => {\n initialize();\n }, [initialize]);\n\n return (\n <div className={clsx(styles.root, isMenuOpen && styles.menuOpen, className)}>\n <SkipLink className={styles.skipLink} href=\"#main-content\">\n {t('common.skipLink')}\n </SkipLink>\n <GlobalHeader routes={routes} appBasePath={appBasePath} />\n <main id=\"main-content\" tabIndex={-1} className={styles.main}>\n {children}\n </main>\n <GlobalFooter />\n </div>\n );\n}","'use client';\n\nimport { Button, Link } from '@digdir/designsystemet-react';\nimport { Search } from 'lucide-react';\nimport clsx from 'clsx';\nimport { Breadcrumbs } from '../Breadcrumbs';\nimport { MenuButton } from '../MenuButton';\nimport { ALLOW_DARK_THEME, useGlobalStore } from '@/store/globalState';\nimport { useLayoutTranslation } from '@/hooks/use-layout-translation';\nimport type { GlobalHeaderProps } from './GlobalHeader.types';\nimport styles from './GlobalHeader.module.css';\n\nexport function GlobalHeader({ className, routes, appBasePath }: 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 toggleDarkMode() {\n setTheme(theme === 'dark' ? 'light' : 'dark');\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\n src=\"https://dok.statsbygg.no/wp-content/uploads/2025/11/Statsbygg_logo.svg\"\n alt=\"Logo\"\n className={styles.logo}\n />\n </Link>\n <div className={styles.actionsContainer}>\n {!isMenuOpen && (\n <>\n {ALLOW_DARK_THEME && (\n <Button onClick={toggleDarkMode} className={styles.themeToggleButton}>\n {theme === 'dark' ? '☀️' : '🌙'}\n </Button>\n )}\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 )}\n <MenuButton appBasePath={appBasePath} />\n </div>\n </div>\n <Breadcrumbs routes={routes} />\n </div>\n </header>\n );\n}","'use client';\n\nimport { useMemo } from 'react';\nimport { usePathname } from 'next/navigation';\nimport { Breadcrumbs } from '@digdir/designsystemet-react';\nimport clsx from 'clsx';\nimport { getBreadcrumbs, findAppRootWithAncestors, BreadcrumbItem } from '@/routes';\nimport { useGlobalStore } from '@/store/globalState';\nimport { useLayoutTranslation } from '@/hooks/use-layout-translation';\nimport type { BreadcrumbsProps } from './Breadcrumbs.types';\nimport styles from './Breadcrumbs.module.css';\n\nexport function SbBreadcrumbs({ className, routes }: BreadcrumbsProps) {\n const pathname = usePathname();\n const manualBreadcrumbs = useGlobalStore((state) => state.breadcrumbs);\n const { t } = useLayoutTranslation();\n\n const breadcrumbs = useMemo((): BreadcrumbItem[] => {\n if (manualBreadcrumbs) {\n const { externalAncestors } = findAppRootWithAncestors(routes);\n const baseBreadcrumbs = externalAncestors.map((node) => ({\n label: node.label,\n href: node.path,\n }));\n const manualHrefs = new Set(manualBreadcrumbs.map((b) => b.href));\n const uniqueBase = baseBreadcrumbs.filter((b) => !manualHrefs.has(b.href));\n return [...uniqueBase, ...manualBreadcrumbs];\n }\n return getBreadcrumbs(routes, pathname);\n }, [routes, pathname, manualBreadcrumbs]);\n\n if (breadcrumbs.length === 0) {\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\n return (\n <Breadcrumbs.Item key={`${crumb.href}-${index}`}>\n <Breadcrumbs.Link\n href={crumb.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 RouteNode = {\n path: string;\n label: string;\n children?: RouteNode[];\n};\n\nexport type BreadcrumbItem = {\n label: string;\n href: string;\n};\n\nfunction isExternalPath(path: string): boolean {\n return path.startsWith('http://') || path.startsWith('https://');\n}\n\nfunction normalizePath(path: string): string {\n if (path === '/') return '/';\n return path.replace(/\\/+$/, '');\n}\n\nfunction formatSegmentLabel(segment: string): string {\n try {\n const decoded = decodeURIComponent(segment).replace(/[-_]+/g, ' ').trim();\n return decoded ? decoded.charAt(0).toUpperCase() + decoded.slice(1) : segment;\n } catch {\n return segment;\n }\n}\n\ntype AncestorChain = {\n externalAncestors: RouteNode[];\n appRoot: RouteNode | null;\n};\n\nexport function findAppRootWithAncestors(node: RouteNode, ancestors: RouteNode[] = []): AncestorChain {\n if (!isExternalPath(node.path)) {\n return {\n externalAncestors: ancestors,\n appRoot: node,\n };\n }\n\n if (node.children) {\n for (const child of node.children) {\n const result = findAppRootWithAncestors(child, [...ancestors, node]);\n if (result.appRoot) return result;\n }\n }\n\n return { externalAncestors: ancestors, appRoot: null };\n}\n\ntype InternalMatch = {\n node: RouteNode;\n ancestors: RouteNode[];\n};\n\nfunction findInternalMatch(\n node: RouteNode,\n pathname: string,\n ancestors: RouteNode[] = []\n): InternalMatch | null {\n const nodePath = normalizePath(node.path);\n\n if (pathname === nodePath) {\n return { node, ancestors };\n }\n\n if (node.children) {\n for (const child of node.children) {\n if (isExternalPath(child.path)) continue;\n\n const result = findInternalMatch(child, pathname, [...ancestors, node]);\n if (result) return result;\n }\n }\n\n const pathPrefix = nodePath === '/' ? '/' : nodePath + '/';\n if (pathname.startsWith(pathPrefix) || pathname === nodePath) {\n return { node, ancestors };\n }\n\n return null;\n}\n\nexport function getBreadcrumbs(routes: RouteNode, pathname: string): BreadcrumbItem[] {\n const normalizedPathname = normalizePath(pathname);\n const { externalAncestors, appRoot } = findAppRootWithAncestors(routes);\n\n if (!appRoot) {\n return externalAncestors.map((node) => ({\n label: node.label,\n href: node.path,\n }));\n }\n\n const breadcrumbs: BreadcrumbItem[] = externalAncestors.map((node) => ({\n label: node.label,\n href: node.path,\n }));\n\n const internalMatch = findInternalMatch(appRoot, normalizedPathname);\n\n if (!internalMatch) {\n breadcrumbs.push({ label: appRoot.label, href: appRoot.path });\n return breadcrumbs;\n }\n\n for (const ancestor of internalMatch.ancestors) {\n breadcrumbs.push({\n label: ancestor.label,\n href: ancestor.path,\n });\n }\n\n breadcrumbs.push({\n label: internalMatch.node.label,\n href: internalMatch.node.path,\n });\n\n const matchedPath = normalizePath(internalMatch.node.path);\n if (normalizedPathname !== matchedPath) {\n const remainingPath = normalizedPathname.slice(\n matchedPath === '/' ? 1 : matchedPath.length + 1\n );\n const dynamicSegments = remainingPath.split('/').filter(Boolean);\n\n let accumulatedPath = matchedPath;\n for (const segment of dynamicSegments) {\n accumulatedPath = accumulatedPath === '/' ? `/${segment}` : `${accumulatedPath}/${segment}`;\n breadcrumbs.push({\n label: formatSegmentLabel(segment),\n href: accumulatedPath,\n });\n }\n }\n\n return breadcrumbs;\n}","import { create, StateCreator } from 'zustand';\nimport { persist, createJSONStorage } from 'zustand/middleware';\nimport type { BreadcrumbItem } from '../routes';\n\nexport type Theme = 'light' | 'dark' | 'system';\n\nexport const ALLOW_DARK_THEME = false;\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;\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);","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 { useLayoutTranslation } from '@/hooks/use-layout-translation';\nimport type { MenuButtonProps } from './MenuButton.types';\n\nexport function MenuButton({ className, appBasePath }: 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 className={className}\n >\n {isMenuOpen ? <X size={20} aria-hidden=\"true\" /> : <Menu size={20} aria-hidden=\"true\" />}\n {isMenuOpen ? t('common.close') : t('common.menu')}\n </Button>\n <NavigationMenu appBasePath={appBasePath} />\n </>\n );\n}","'use client';\n\nimport { useState, useEffect, useRef } from 'react';\nimport { Heading, Search } from '@digdir/designsystemet-react';\nimport { NAVIGATION_MENU, MenuSection } from '../../navigationMenu';\nimport { NavigationMenuItem } from '../NavigationMenuItem/NavigationMenuItem';\nimport { useGlobalStore } from '../../store/globalState';\nimport { useLayoutTranslation } from '@/hooks/use-layout-translation';\nimport type { NavigationMenuProps } from './NavigationMenu.types';\nimport styles from './NavigationMenu.module.css';\n\nexport function NavigationMenu({ className, appBasePath }: 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 const { t } = useLayoutTranslation();\n\n useEffect(() => {\n if (!isMenuOpen) return;\n\n function 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 return () => document.removeEventListener('keydown', handleEscape);\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 : ''} ${className ?? ''}`}>\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 className={styles.menuSections} aria-label={t('menu.mainMenuLabel')}>\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 {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={\n 150 + sectionIndex * 60 + subsectionIndex * 40 + itemIndex * 25\n }\n appBasePath={appBasePath}\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 appBasePath={appBasePath}\n />\n ))}\n </div>\n )}\n </section>\n ))}\n </nav>\n </div>\n </div>\n </>\n );\n}","export type MenuItem = {\n label: string;\n href: string;\n external?: boolean;\n children?: MenuItem[];\n};\n\nexport type MenuSubsection = {\n title: string;\n items: MenuItem[];\n};\n\nexport type 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: '/for-leietakere/leieveileder' },\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 ],\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];","'use client';\n\nimport { List } from '@digdir/designsystemet-react';\nimport { ExternalLink } from 'lucide-react';\nimport { usePathname } from 'next/navigation';\nimport clsx from 'clsx';\nimport { SmartLink } from '../SmartLink';\nimport type { MenuItem } from '../../navigationMenu';\nimport type { NavigationMenuItemProps } from './NavigationMenuItem.types';\nimport styles from './NavigationMenuItem.module.css';\n\nexport function NavigationMenuItem({\n item,\n animationDelay,\n compact = false,\n appBasePath,\n}: NavigationMenuItemProps) {\n const pathname = usePathname();\n\n const isActive = (href: string) => {\n if (href === '/') return pathname === '/';\n return pathname?.startsWith(href);\n };\n\n const isParentActive = isActive(item.href);\n\n if (compact) {\n return (\n <div\n className={styles.itemColumn}\n style={{ animationDelay: `${animationDelay}ms` }}\n >\n <SmartLink\n href={item.href}\n appBasePath={appBasePath}\n external={item.external}\n className={clsx(styles.compactLink, isParentActive && styles.active)}\n >\n {item.label}\n {item.external && <ExternalLink size={16} aria-hidden=\"true\" />}\n </SmartLink>\n </div>\n );\n }\n\n return (\n <div\n className={styles.itemColumn}\n style={{ animationDelay: `${animationDelay}ms` }}\n >\n <SmartLink\n href={item.href}\n appBasePath={appBasePath}\n external={item.external}\n className={clsx(styles.parentLink, isParentActive && styles.active)}\n >\n {item.label}\n {item.external && <ExternalLink size={20} aria-hidden=\"true\" />}\n </SmartLink>\n\n {item.children && item.children.length > 0 && (\n <List.Unordered className={styles.childItems}>\n {item.children.map((child: MenuItem, childIndex: number) => {\n const isChildActive = isActive(child.href);\n\n return (\n <List.Item\n key={childIndex}\n className={styles.childItem}\n style={{ animationDelay: `${animationDelay + 30 + childIndex * 15}ms` }}\n >\n <SmartLink\n href={child.href}\n appBasePath={appBasePath}\n external={child.external}\n className={clsx(styles.childLink, isChildActive && styles.active)}\n >\n {child.label}\n {child.external && <ExternalLink size={16} aria-hidden=\"true\" />}\n </SmartLink>\n </List.Item>\n );\n })}\n </List.Unordered>\n )}\n </div>\n );\n}","'use client';\n\nimport Link from 'next/link';\nimport { Link as DsLink } from '@digdir/designsystemet-react';\nimport type { SmartLinkProps } from './SmartLink.types';\n\n/**\n * Determines if a given href belongs to the current zone, another zone or should be external\n */\nexport function SmartLink({\n href,\n appBasePath,\n external = false,\n className,\n children,\n}: SmartLinkProps) {\n const isExternalUrl = href.startsWith('http://') || href.startsWith('https://');\n const isLocalRoute =\n appBasePath &&\n !isExternalUrl &&\n (href === appBasePath || href.startsWith(`${appBasePath}/`));\n\n if (isExternalUrl || external) {\n return (\n <DsLink\n href={href}\n className={className}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n >\n {children}\n </DsLink>\n );\n }\n\n if (isLocalRoute) {\n // Strip the basePath\n const localHref = href.replace(appBasePath, '') || '/';\n\n return (\n <Link href={localHref} className={className}>\n {children}\n </Link>\n );\n }\n\n // Cross-zone navigation: use standard anchor for full page load\n return (\n <DsLink href={href} className={className}>\n {children}\n </DsLink>\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 } from 'react';\nimport { useGlobalStore } from '../store/globalState';\nimport type { BreadcrumbItem } from '../routes';\n\n/**\n * Hook for manually setting breadcrumbs on dynamic routes.\n * Overrides automatic breadcrumb generation, preserving external ancestors.\n *\n * @param breadcrumbs - Array of breadcrumb items for the current dynamic route\n */\nexport function useBreadcrumbs(breadcrumbs: BreadcrumbItem[]): void {\n const setBreadcrumbs = useGlobalStore((state) => state.setBreadcrumbs);\n const serialized = JSON.stringify(breadcrumbs);\n\n useEffect(() => {\n setBreadcrumbs(JSON.parse(serialized));\n\n return () => {\n setBreadcrumbs(null);\n };\n }, [serialized, setBreadcrumbs]);\n}"],"mappings":"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","names":["useEffect","clsx","Button","Link","Search","clsx","usePathname","clsx","jsx","styles","jsx","usePathname","clsx","styles","jsx","jsxs","Fragment","jsx","jsxs","styles","Fragment","jsx","jsxs","clsx","Link","Button","Search","clsx","styles","jsx","clsx","styles","styles","jsx","jsxs","useEffect","clsx","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/BreadcrumbLink/BreadcrumbLink.tsx","../src/components/MenuButton/MenuButton.tsx","../src/components/NavigationMenu/NavigationMenu.tsx","../src/navigationMenu.ts","../src/components/NavigationMenuItem/NavigationMenuItem.tsx","../src/components/SmartLink/SmartLink.tsx","../src/components/GlobalFooter/GlobalFooter.tsx","../src/hooks/use-breadcrumbs.ts"],"sourcesContent":["'use client';\n\nimport { useEffect } from 'react';\nimport clsx from 'clsx';\nimport { SkipLink } from '@digdir/designsystemet-react';\nimport { GlobalHeader } from '../GlobalHeader';\nimport { GlobalFooter } from '../GlobalFooter';\nimport { useGlobalStore } from '@/store/globalState';\nimport { useLayoutTranslation } from '@/hooks/use-layout-translation';\nimport type { RootLayoutProps } from './RootLayout.types';\nimport styles from './RootLayout.module.css';\n\nexport function RootLayout({ children, routes, appBasePath, className }: RootLayoutProps) {\n const initialize = useGlobalStore((state) => state.initialize);\n const isMenuOpen = useGlobalStore((state) => state.isMenuOpen);\n const { t } = useLayoutTranslation();\n\n useEffect(() => {\n initialize();\n }, [initialize]);\n\n return (\n <div className={clsx(styles.root, isMenuOpen && styles.menuOpen, className)}>\n <SkipLink className={styles.skipLink} href=\"#main-content\">\n {t('common.skipLink')}\n </SkipLink>\n <GlobalHeader routes={routes} appBasePath={appBasePath} />\n <main id=\"main-content\" tabIndex={-1} className={styles.main}>\n {children}\n </main>\n <GlobalFooter />\n </div>\n );\n}","'use client';\n\nimport { Button, Link } from '@digdir/designsystemet-react';\nimport { Search } from 'lucide-react';\nimport clsx from 'clsx';\nimport { Breadcrumbs } from '../Breadcrumbs';\nimport { MenuButton } from '../MenuButton';\nimport { ALLOW_DARK_THEME, useGlobalStore } from '@/store/globalState';\nimport { useLayoutTranslation } from '@/hooks/use-layout-translation';\nimport type { GlobalHeaderProps } from './GlobalHeader.types';\nimport styles from './GlobalHeader.module.css';\n\nexport function GlobalHeader({ className, routes, appBasePath }: 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 toggleDarkMode() {\n setTheme(theme === 'dark' ? 'light' : 'dark');\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\n src=\"https://dok.statsbygg.no/wp-content/uploads/2025/11/Statsbygg_logo.svg\"\n alt=\"Logo\"\n className={styles.logo}\n />\n </Link>\n <div className={styles.actionsContainer}>\n {!isMenuOpen && (\n <>\n {ALLOW_DARK_THEME && (\n <Button onClick={toggleDarkMode} className={styles.themeToggleButton}>\n {theme === 'dark' ? '☀️' : '🌙'}\n </Button>\n )}\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 )}\n <MenuButton appBasePath={appBasePath} />\n </div>\n </div>\n <Breadcrumbs routes={routes} appBasePath={appBasePath} />\n </div>\n </header>\n );\n}","'use client';\n\nimport { useMemo } from 'react';\nimport { usePathname } from 'next/navigation';\nimport { Breadcrumbs } from '@digdir/designsystemet-react';\nimport clsx from 'clsx';\nimport { getBreadcrumbs, findAppRootWithAncestors, BreadcrumbItem } from '@/routes';\nimport { useGlobalStore } from '@/store/globalState';\nimport { useLayoutTranslation } from '@/hooks/use-layout-translation';\nimport { BreadcrumbLink } from '../BreadcrumbLink';\nimport type { BreadcrumbsProps } from './Breadcrumbs.types';\nimport styles from './Breadcrumbs.module.css';\n\nexport function SbBreadcrumbs({ className, routes, appBasePath }: BreadcrumbsProps) {\n const pathname = usePathname();\n const manualBreadcrumbs = useGlobalStore((state) => state.breadcrumbs);\n const { t } = useLayoutTranslation();\n\n const breadcrumbs = useMemo((): BreadcrumbItem[] => {\n if (manualBreadcrumbs) {\n const { externalAncestors } = findAppRootWithAncestors(routes);\n const baseBreadcrumbs = externalAncestors.map((node) => ({\n label: node.label,\n href: node.path,\n }));\n const manualHrefs = new Set(manualBreadcrumbs.map((b) => b.href));\n const uniqueBase = baseBreadcrumbs.filter((b) => !manualHrefs.has(b.href));\n return [...uniqueBase, ...manualBreadcrumbs];\n }\n return getBreadcrumbs(routes, pathname);\n }, [routes, pathname, manualBreadcrumbs]);\n\n if (breadcrumbs.length === 0) {\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\n return (\n <Breadcrumbs.Item key={`${crumb.href}-${index}`}>\n <BreadcrumbLink\n href={crumb.href}\n ariaCurrent={isLast ? 'page' : undefined}\n className={isLast ? styles.currentLink : styles.link}\n >\n {crumb.label}\n </BreadcrumbLink>\n </Breadcrumbs.Item>\n );\n })}\n </Breadcrumbs.List>\n </Breadcrumbs>\n );\n}","export type RouteNode = {\n path: string;\n label: string;\n children?: RouteNode[];\n};\n\nexport type BreadcrumbItem = {\n label: string;\n href: string;\n};\n\nfunction isExternalPath(path: string): boolean {\n return path.startsWith('http://') || path.startsWith('https://');\n}\n\nfunction normalizePath(path: string): string {\n if (path === '/') return '/';\n return path.replace(/\\/+$/, '');\n}\n\nfunction formatSegmentLabel(segment: string): string {\n try {\n const decoded = decodeURIComponent(segment).replace(/[-_]+/g, ' ').trim();\n return decoded ? decoded.charAt(0).toUpperCase() + decoded.slice(1) : segment;\n } catch {\n return segment;\n }\n}\n\ntype AncestorChain = {\n externalAncestors: RouteNode[];\n appRoot: RouteNode | null;\n};\n\nexport function findAppRootWithAncestors(node: RouteNode, ancestors: RouteNode[] = []): AncestorChain {\n if (!isExternalPath(node.path)) {\n return {\n externalAncestors: ancestors,\n appRoot: node,\n };\n }\n\n if (node.children) {\n for (const child of node.children) {\n const result = findAppRootWithAncestors(child, [...ancestors, node]);\n if (result.appRoot) return result;\n }\n }\n\n return { externalAncestors: ancestors, appRoot: null };\n}\n\ntype InternalMatch = {\n node: RouteNode;\n ancestors: RouteNode[];\n};\n\nfunction findInternalMatch(\n node: RouteNode,\n pathname: string,\n ancestors: RouteNode[] = []\n): InternalMatch | null {\n const nodePath = normalizePath(node.path);\n\n if (pathname === nodePath) {\n return { node, ancestors };\n }\n\n if (node.children) {\n for (const child of node.children) {\n if (isExternalPath(child.path)) continue;\n\n const result = findInternalMatch(child, pathname, [...ancestors, node]);\n if (result) return result;\n }\n }\n\n const pathPrefix = nodePath === '/' ? '/' : nodePath + '/';\n if (pathname.startsWith(pathPrefix) || pathname === nodePath) {\n return { node, ancestors };\n }\n\n return null;\n}\n\nexport function getBreadcrumbs(routes: RouteNode, pathname: string): BreadcrumbItem[] {\n const normalizedPathname = normalizePath(pathname);\n const { externalAncestors, appRoot } = findAppRootWithAncestors(routes);\n\n if (!appRoot) {\n return externalAncestors.map((node) => ({\n label: node.label,\n href: node.path,\n }));\n }\n\n const breadcrumbs: BreadcrumbItem[] = externalAncestors.map((node) => ({\n label: node.label,\n href: node.path,\n }));\n\n const internalMatch = findInternalMatch(appRoot, normalizedPathname);\n\n if (!internalMatch) {\n breadcrumbs.push({ label: appRoot.label, href: appRoot.path });\n return breadcrumbs;\n }\n\n for (const ancestor of internalMatch.ancestors) {\n breadcrumbs.push({\n label: ancestor.label,\n href: ancestor.path,\n });\n }\n\n breadcrumbs.push({\n label: internalMatch.node.label,\n href: internalMatch.node.path,\n });\n\n const matchedPath = normalizePath(internalMatch.node.path);\n if (normalizedPathname !== matchedPath) {\n const remainingPath = normalizedPathname.slice(\n matchedPath === '/' ? 1 : matchedPath.length + 1\n );\n const dynamicSegments = remainingPath.split('/').filter(Boolean);\n\n let accumulatedPath = matchedPath;\n for (const segment of dynamicSegments) {\n accumulatedPath = accumulatedPath === '/' ? `/${segment}` : `${accumulatedPath}/${segment}`;\n breadcrumbs.push({\n label: formatSegmentLabel(segment),\n href: accumulatedPath,\n });\n }\n }\n\n return breadcrumbs;\n}","import { create, StateCreator } from 'zustand';\nimport { persist, createJSONStorage } from 'zustand/middleware';\nimport type { BreadcrumbItem } from '../routes';\n\nexport type Theme = 'light' | 'dark' | 'system';\n\nexport const ALLOW_DARK_THEME = false;\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;\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);","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 Link from 'next/link';\nimport type { ReactNode } from 'react';\n\ntype BreadcrumbLinkProps = {\n href: string;\n className?: string;\n ariaCurrent?: 'page' | undefined;\n children: ReactNode;\n};\n\n/**\n * Renders breadcrumb links correctly:\n * - External URLs (http/https): standard anchor tag\n * - Internal paths: Next.js Link (handles basePath automatically)\n */\nexport function BreadcrumbLink({\n href,\n className,\n ariaCurrent,\n children,\n}: BreadcrumbLinkProps) {\n const isExternal = href.startsWith('http://') || href.startsWith('https://');\n\n if (isExternal) {\n return (\n <a href={href} className={className} aria-current={ariaCurrent}>\n {children}\n </a>\n );\n }\n\n return (\n <Link href={href} className={className} aria-current={ariaCurrent}>\n {children}\n </Link>\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 { useLayoutTranslation } from '@/hooks/use-layout-translation';\nimport type { MenuButtonProps } from './MenuButton.types';\n\nexport function MenuButton({ className, appBasePath }: 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 className={className}\n >\n {isMenuOpen ? <X size={20} aria-hidden=\"true\" /> : <Menu size={20} aria-hidden=\"true\" />}\n {isMenuOpen ? t('common.close') : t('common.menu')}\n </Button>\n <NavigationMenu appBasePath={appBasePath} />\n </>\n );\n}","'use client';\n\nimport { useState, useEffect, useRef } from 'react';\nimport { Heading, Search } from '@digdir/designsystemet-react';\nimport { NAVIGATION_MENU, MenuSection } from '../../navigationMenu';\nimport { NavigationMenuItem } from '../NavigationMenuItem/NavigationMenuItem';\nimport { useGlobalStore } from '../../store/globalState';\nimport { useLayoutTranslation } from '@/hooks/use-layout-translation';\nimport type { NavigationMenuProps } from './NavigationMenu.types';\nimport styles from './NavigationMenu.module.css';\n\nexport function NavigationMenu({ className, appBasePath }: 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 const { t } = useLayoutTranslation();\n\n useEffect(() => {\n if (!isMenuOpen) return;\n\n function 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 return () => document.removeEventListener('keydown', handleEscape);\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 : ''} ${className ?? ''}`}>\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 className={styles.menuSections} aria-label={t('menu.mainMenuLabel')}>\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 {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={\n 150 + sectionIndex * 60 + subsectionIndex * 40 + itemIndex * 25\n }\n appBasePath={appBasePath}\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 appBasePath={appBasePath}\n />\n ))}\n </div>\n )}\n </section>\n ))}\n </nav>\n </div>\n </div>\n </>\n );\n}","export type MenuItem = {\n label: string;\n href: string;\n external?: boolean;\n children?: MenuItem[];\n};\n\nexport type MenuSubsection = {\n title: string;\n items: MenuItem[];\n};\n\nexport type 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: '/for-leietakere/leieveileder' },\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 ],\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];","'use client';\n\nimport { List } from '@digdir/designsystemet-react';\nimport { ExternalLink } from 'lucide-react';\nimport { usePathname } from 'next/navigation';\nimport clsx from 'clsx';\nimport { SmartLink } from '../SmartLink';\nimport type { MenuItem } from '../../navigationMenu';\nimport type { NavigationMenuItemProps } from './NavigationMenuItem.types';\nimport styles from './NavigationMenuItem.module.css';\n\nexport function NavigationMenuItem({\n item,\n animationDelay,\n compact = false,\n appBasePath,\n}: NavigationMenuItemProps) {\n const pathname = usePathname();\n\n const isActive = (href: string) => {\n if (href === '/') return pathname === '/';\n return pathname?.startsWith(href);\n };\n\n const isParentActive = isActive(item.href);\n\n if (compact) {\n return (\n <div\n className={styles.itemColumn}\n style={{ animationDelay: `${animationDelay}ms` }}\n >\n <SmartLink\n href={item.href}\n appBasePath={appBasePath}\n external={item.external}\n className={clsx(styles.compactLink, isParentActive && styles.active)}\n >\n {item.label}\n {item.external && <ExternalLink size={16} aria-hidden=\"true\" />}\n </SmartLink>\n </div>\n );\n }\n\n return (\n <div\n className={styles.itemColumn}\n style={{ animationDelay: `${animationDelay}ms` }}\n >\n <SmartLink\n href={item.href}\n appBasePath={appBasePath}\n external={item.external}\n className={clsx(styles.parentLink, isParentActive && styles.active)}\n >\n {item.label}\n {item.external && <ExternalLink size={20} aria-hidden=\"true\" />}\n </SmartLink>\n\n {item.children && item.children.length > 0 && (\n <List.Unordered className={styles.childItems}>\n {item.children.map((child: MenuItem, childIndex: number) => {\n const isChildActive = isActive(child.href);\n\n return (\n <List.Item\n key={childIndex}\n className={styles.childItem}\n style={{ animationDelay: `${animationDelay + 30 + childIndex * 15}ms` }}\n >\n <SmartLink\n href={child.href}\n appBasePath={appBasePath}\n external={child.external}\n className={clsx(styles.childLink, isChildActive && styles.active)}\n >\n {child.label}\n {child.external && <ExternalLink size={16} aria-hidden=\"true\" />}\n </SmartLink>\n </List.Item>\n );\n })}\n </List.Unordered>\n )}\n </div>\n );\n}","'use client';\n\nimport Link from 'next/link';\nimport { Link as DsLink } from '@digdir/designsystemet-react';\nimport type { SmartLinkProps } from './SmartLink.types';\n\n/**\n * Determines if a given href belongs to the current zone, another zone or should be external\n */\nexport function SmartLink({\n href,\n appBasePath,\n external = false,\n className,\n children,\n}: SmartLinkProps) {\n const isExternalUrl = href.startsWith('http://') || href.startsWith('https://');\n const isLocalRoute =\n appBasePath &&\n !isExternalUrl &&\n (href === appBasePath || href.startsWith(`${appBasePath}/`));\n\n if (isExternalUrl || external) {\n return (\n <DsLink\n href={href}\n className={className}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n >\n {children}\n </DsLink>\n );\n }\n\n if (isLocalRoute) {\n // Strip the basePath\n const localHref = href.replace(appBasePath, '') || '/';\n\n return (\n <Link href={localHref} className={className}>\n {children}\n </Link>\n );\n }\n\n // Cross-zone navigation: use standard anchor for full page load\n return (\n <DsLink href={href} className={className}>\n {children}\n </DsLink>\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 } from 'react';\nimport { useGlobalStore } from '../store/globalState';\nimport type { BreadcrumbItem } from '../routes';\n\n/**\n * Hook for manually setting breadcrumbs on dynamic routes.\n * Overrides automatic breadcrumb generation, preserving external ancestors.\n *\n * @param breadcrumbs - Array of breadcrumb items for the current dynamic route\n */\nexport function useBreadcrumbs(breadcrumbs: BreadcrumbItem[]): void {\n const setBreadcrumbs = useGlobalStore((state) => state.setBreadcrumbs);\n const serialized = JSON.stringify(breadcrumbs);\n\n useEffect(() => {\n setBreadcrumbs(JSON.parse(serialized));\n\n return () => {\n setBreadcrumbs(null);\n };\n }, [serialized, setBreadcrumbs]);\n}"],"mappings":"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","names":["useEffect","clsx","Button","Link","Search","clsx","jsx","usePathname","clsx","Link","jsx","styles","jsx","usePathname","clsx","styles","jsx","jsxs","Fragment","jsx","jsxs","styles","Fragment","jsx","jsxs","clsx","Link","Button","Search","clsx","styles","jsx","clsx","styles","styles","jsx","jsxs","useEffect","clsx","useEffect","useEffect"]}
|
package/package.json
CHANGED