@statsbygg/layout 0.0.2 → 0.0.4
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 +2 -2
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +3 -2
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
"use client";
|
|
2
3
|
var __create = Object.create;
|
|
3
4
|
var __defProp = Object.defineProperty;
|
|
4
5
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
@@ -285,13 +286,12 @@ var GlobalHeader_default = {
|
|
|
285
286
|
var logo_default = "./logo-X7RC63NT.svg";
|
|
286
287
|
|
|
287
288
|
// src/components/GlobalHeader/GlobalHeader.tsx
|
|
288
|
-
var import_image = __toESM(require("next/image"));
|
|
289
289
|
var import_jsx_runtime3 = require("react/jsx-runtime");
|
|
290
290
|
function GlobalHeader({ className, zone }) {
|
|
291
291
|
const [searchValue, setSearchValue] = (0, import_react.useState)("");
|
|
292
292
|
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("header", { className: (0, import_clsx2.default)(GlobalHeader_default.header, className), children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: GlobalHeader_default.headerContainer, children: [
|
|
293
293
|
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: GlobalHeader_default.topBarContainer, children: [
|
|
294
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_designsystemet_react3.Link, { href: "https://www.statsbygg.no", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
294
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_designsystemet_react3.Link, { href: "https://www.statsbygg.no", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("img", { src: logo_default, alt: "Logo", className: GlobalHeader_default.logo }) }),
|
|
295
295
|
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: GlobalHeader_default.actionsContainer, children: [
|
|
296
296
|
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
297
297
|
import_designsystemet_react3.Textfield,
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/components/RootLayout/RootLayout.tsx","../src/components/GlobalHeader/GlobalHeader.tsx","../src/components/Breadcrumbs/Breadcrumbs.tsx","../src/components/Breadcrumbs/Breadcrumbs.module.css","../src/routes.ts","../src/components/MenuButton/MenuButton.tsx","../src/components/MenuButton/MenuButton.module.css","../src/components/GlobalHeader/GlobalHeader.module.css","../src/components/GlobalFooter/GlobalFooter.tsx","../src/components/GlobalFooter/GlobalFooter.module.css","../src/components/RootLayout/RootLayout.module.css","../src/store/globalState.ts"],"sourcesContent":["\nexport { RootLayout } from './components/RootLayout';\nexport type { RootLayoutProps } from './components/RootLayout';\n\nexport { useGlobalStore } from './store/globalState';\nexport type { GlobalState } from './store/globalState';\n","'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';\n\nexport function RootLayout({\n children,\n zone, \n className,\n}: RootLayoutProps) {\n const initialize = useGlobalStore((state) => state.initialize);\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, className)} data-zone={zone}>\n <GlobalHeader zone={zone}/>\n <main className={styles.main}>{children}</main>\n <GlobalFooter />\n </div>\n );\n}\n","'use client';\n\nimport { useState } from 'react';\nimport { Link, Textfield } 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 logo from '../../logo.svg'; \nimport Image from 'next/image';\n\nexport function GlobalHeader({ className, zone }: GlobalHeaderProps) {\n const [searchValue, setSearchValue] = useState('');\n\n return (\n <header className={clsx(styles.header, className)}>\n <div className={styles.headerContainer}>\n <div className={styles.topBarContainer}>\n <Link href=\"https://www.statsbygg.no\">\n <Image src={logo} alt=\"Logo\" className={styles.logo} />\n </Link>\n <div className={styles.actionsContainer}>\n <Textfield\n value={searchValue}\n onChange={(e) => setSearchValue(e.target.value)}\n placeholder=\"Søk...\"\n className={styles.searchInput}\n aria-label=\"Søk\"\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';\n\nexport function SbBreadcrumbs({ className, zone }: BreadcrumbsProps) {\n const pathname = usePathname();\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 = getBreadcrumbs(zone, fullPath);\n\n if (breadcrumbs.length <= 1) {\n return null;\n }\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 = 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}",".breadcrumbs {\n --dsc-breadcrumbs-color: var(--ds-color-text-default);\n padding: 2.5rem 0 0 0;\n}\n\n.link {\n text-decoration: underline;\n text-underline-offset: 2px;\n color: var(--ds-color-text-default);\n}\n\n.link:hover \n.link:visited{\n color: var(--ds-color-text-default);\n}\n\n.currentLink {\n text-decoration: none;\n font-weight: 500;\n pointer-events: none;\n color: var(--ds-color-text-default);\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}","'use client';\n\nimport Link from 'next/link';\nimport { Dropdown } from '@digdir/designsystemet-react';\nimport { Menu } from 'lucide-react';\nimport { getZoneMenuRoutes, getAllZones, transformHrefForZone } from '@/routes';\nimport type { MenuButtonProps } from './MenuButton.types';\nimport styles from './MenuButton.module.css';\n\nexport function MenuButton({ zone }: MenuButtonProps) {\n const isDev = process.env.NODE_ENV === 'development';\n // TODO: Temporary here. Should come from env or something\n const prodUrl = 'https://www.statsbygg.no';\n const allZones = getAllZones();\n\n return (\n <Dropdown.TriggerContext>\n <Dropdown.Trigger asChild className={styles.menuButton}>\n <Menu size={20} aria-hidden />\n Meny\n </Dropdown.Trigger>\n <Dropdown>\n {isDev ? (\n <div className={styles.devContainer}>\n {allZones.map((z) => {\n const routes = getZoneMenuRoutes(z);\n return (\n <div key={z} className={styles.zoneSection}>\n <div className={styles.zoneTitle}>{z}</div>\n <Dropdown.List>\n {routes.map((r) => (\n <Dropdown.Item key={`${r.zone}:${r.path}`}>\n <Link href={transformHrefForZone(r.path, zone, { isDev, prodUrl })}>\n {r.label}\n </Link>\n </Dropdown.Item>\n ))}\n </Dropdown.List>\n </div>\n );\n })}\n </div>\n ) : (\n <Dropdown.List>\n {getZoneMenuRoutes(zone).map((r) => (\n <Dropdown.Item key={`${r.zone}:${r.path}`}>\n <Link href={transformHrefForZone(r.path, zone, { isDev, prodUrl })}>\n {r.label}\n </Link>\n </Dropdown.Item>\n ))}\n </Dropdown.List>\n )}\n </Dropdown>\n </Dropdown.TriggerContext>\n );\n}",".userInfo {\n display: flex;\n flex-direction: column;\n gap: var(--ds-spacing-1);\n padding: var(--ds-spacing-2) var(--ds-spacing-3);\n}\n\n.userName {\n font-size: var(--ds-font-size-sm);\n font-weight: var(--ds-font-weight-medium);\n color: var(--ds-color-neutral-text-default);\n}\n\n.userEmail {\n font-size: var(--ds-font-size-xs);\n color: var(--ds-color-neutral-text-subtle);\n}\n\n.menuButton {\n background-color: var(--ds-color-neutral-base-default);\n}\n\n.devContainer {\n display: flex;\n gap: var(--ds-spacing-4);\n padding: var(--ds-spacing-2);\n}\n\n.zoneSection {\n flex: 1;\n min-width: 12rem;\n}\n\n.zoneTitle {\n font-weight: 600;\n padding: var(--ds-spacing-2);\n color: var(--ds-color-neutral-text-default);\n border-bottom: 1px solid var(--ds-color-neutral-border-subtle);\n margin-bottom: var(--ds-spacing-2);\n text-transform: capitalize;\n}\n",".header {\n background-color: var(--ds-color-accent-surface-tinted);\n border-bottom: 1px solid var(--ds-color-neutral-border-subtle);\n position: sticky;\n top: 0;\n z-index: 100;\n}\n\n.headerContainer {\n max-width: 90rem;\n margin: 0 auto;\n padding: 0 var(--ds-size-30);\n}\n\n.topBarContainer {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 1.25rem 0;\n}\n\n.logo {\n margin: 0;\n color: var(--ds-color-neutral-text-default);\n white-space: nowrap;\n display: flex;\n align-items: center;\n min-height: inherit;\n}\n\n.actionsContainer {\n display: flex;\n align-items: stretch;\n gap: var(--ds-size-9);\n min-height: inherit;\n}\n\n.searchInput {\n min-width: 12.5rem;\n display: flex;\n align-items: center;\n}\n\n@media (max-width: 768px) {\n .container {\n padding: 0 var(--ds-spacing-4);\n }\n\n .topBar {\n flex-wrap: wrap;\n padding: var(--ds-spacing-4) 0;\n }\n\n .actions {\n order: 3;\n width: 100%;\n flex-direction: column;\n gap: var(--ds-spacing-3);\n }\n\n .searchInput {\n width: 100%;\n min-width: auto;\n }\n\n .menuButton {\n width: 100%;\n justify-content: center;\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}",".footer {\n background-color: var(--ds-color-neutral-surface-subtle);\n border-top: 1px solid var(--ds-color-neutral-border-subtle);\n margin-top: auto;\n}\n\n.container {\n max-width: 1440px;\n margin: 0 auto;\n padding: var(--ds-spacing-6) var(--ds-spacing-4);\n}\n\n.content {\n display: flex;\n justify-content: space-between;\n align-items: center;\n gap: var(--ds-spacing-4);\n flex-wrap: wrap;\n}\n\n@media (max-width: 768px) {\n .content {\n flex-direction: column;\n align-items: flex-start;\n }\n\n\n}",".root {\n display: flex;\n flex-direction: column;\n min-height: 100vh;\n}\n\n.main {\n flex: 1;\n}","import { create, StateCreator } from 'zustand';\nimport { persist, createJSONStorage } from 'zustand/middleware';\n\nexport type Theme = 'light' | 'dark' | 'system';\n\nexport type GlobalState = {\n user?: { id: string; name?: string } | null;\n theme: Theme;\n locale: string;\n setUser: (user: GlobalState['user']) => void;\n setTheme: (theme: Theme) => void;\n setLocale: (locale: string) => 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 setUser: (user) => set({ user }),\n setTheme: (theme) => {\n set({ theme });\n if (typeof document !== 'undefined') {\n document.documentElement.setAttribute('data-color-scheme', theme);\n }\n },\n setLocale: (locale) => set({ locale }),\n initialize: () => {\n if (typeof document !== 'undefined') {\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 })\n);\n"],"mappings":"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","names":["import_react","import_clsx","import_designsystemet_react","import_clsx","breadcrumbs","link","currentLink","_a","clsx","import_designsystemet_react","userInfo","userName","userEmail","menuButton","devContainer","zoneSection","zoneTitle","import_jsx_runtime","Link","header","headerContainer","topBarContainer","logo","actionsContainer","searchInput","container","topBar","actions","menuButton","import_jsx_runtime","clsx","Image","import_designsystemet_react","import_clsx","footer","container","content","import_jsx_runtime","clsx","root","main","import_jsx_runtime","clsx"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/components/RootLayout/RootLayout.tsx","../src/components/GlobalHeader/GlobalHeader.tsx","../src/components/Breadcrumbs/Breadcrumbs.tsx","../src/components/Breadcrumbs/Breadcrumbs.module.css","../src/routes.ts","../src/components/MenuButton/MenuButton.tsx","../src/components/MenuButton/MenuButton.module.css","../src/components/GlobalHeader/GlobalHeader.module.css","../src/components/GlobalFooter/GlobalFooter.tsx","../src/components/GlobalFooter/GlobalFooter.module.css","../src/components/RootLayout/RootLayout.module.css","../src/store/globalState.ts"],"sourcesContent":["'use client';\n\nexport { RootLayout } from './components/RootLayout';\nexport type { RootLayoutProps } from './components/RootLayout';\n\nexport { useGlobalStore } from './store/globalState';\nexport type { GlobalState } from './store/globalState';\n","'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';\n\nexport function RootLayout({\n children,\n zone, \n className,\n}: RootLayoutProps) {\n const initialize = useGlobalStore((state) => state.initialize);\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, className)} data-zone={zone}>\n <GlobalHeader zone={zone}/>\n <main className={styles.main}>{children}</main>\n <GlobalFooter />\n </div>\n );\n}\n","'use client';\n\nimport { useState } from 'react';\nimport { Link, Textfield } 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 logo from '../../logo.svg'; \n\nexport function GlobalHeader({ className, zone }: GlobalHeaderProps) {\n const [searchValue, setSearchValue] = useState('');\n\n return (\n <header className={clsx(styles.header, className)}>\n <div className={styles.headerContainer}>\n <div className={styles.topBarContainer}>\n <Link href=\"https://www.statsbygg.no\">\n <img src={logo} alt=\"Logo\" className={styles.logo} />\n </Link>\n <div className={styles.actionsContainer}>\n <Textfield\n value={searchValue}\n onChange={(e) => setSearchValue(e.target.value)}\n placeholder=\"Søk...\"\n className={styles.searchInput}\n aria-label=\"Søk\"\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';\n\nexport function SbBreadcrumbs({ className, zone }: BreadcrumbsProps) {\n const pathname = usePathname();\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 = getBreadcrumbs(zone, fullPath);\n\n if (breadcrumbs.length <= 1) {\n return null;\n }\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 = 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}",".breadcrumbs {\n --dsc-breadcrumbs-color: var(--ds-color-text-default);\n padding: 2.5rem 0 0 0;\n}\n\n.link {\n text-decoration: underline;\n text-underline-offset: 2px;\n color: var(--ds-color-text-default);\n}\n\n.link:hover \n.link:visited{\n color: var(--ds-color-text-default);\n}\n\n.currentLink {\n text-decoration: none;\n font-weight: 500;\n pointer-events: none;\n color: var(--ds-color-text-default);\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}","'use client';\n\nimport Link from 'next/link';\nimport { Dropdown } from '@digdir/designsystemet-react';\nimport { Menu } from 'lucide-react';\nimport { getZoneMenuRoutes, getAllZones, transformHrefForZone } from '@/routes';\nimport type { MenuButtonProps } from './MenuButton.types';\nimport styles from './MenuButton.module.css';\n\nexport function MenuButton({ zone }: MenuButtonProps) {\n const isDev = process.env.NODE_ENV === 'development';\n // TODO: Temporary here. Should come from env or something\n const prodUrl = 'https://www.statsbygg.no';\n const allZones = getAllZones();\n\n return (\n <Dropdown.TriggerContext>\n <Dropdown.Trigger asChild className={styles.menuButton}>\n <Menu size={20} aria-hidden />\n Meny\n </Dropdown.Trigger>\n <Dropdown>\n {isDev ? (\n <div className={styles.devContainer}>\n {allZones.map((z) => {\n const routes = getZoneMenuRoutes(z);\n return (\n <div key={z} className={styles.zoneSection}>\n <div className={styles.zoneTitle}>{z}</div>\n <Dropdown.List>\n {routes.map((r) => (\n <Dropdown.Item key={`${r.zone}:${r.path}`}>\n <Link href={transformHrefForZone(r.path, zone, { isDev, prodUrl })}>\n {r.label}\n </Link>\n </Dropdown.Item>\n ))}\n </Dropdown.List>\n </div>\n );\n })}\n </div>\n ) : (\n <Dropdown.List>\n {getZoneMenuRoutes(zone).map((r) => (\n <Dropdown.Item key={`${r.zone}:${r.path}`}>\n <Link href={transformHrefForZone(r.path, zone, { isDev, prodUrl })}>\n {r.label}\n </Link>\n </Dropdown.Item>\n ))}\n </Dropdown.List>\n )}\n </Dropdown>\n </Dropdown.TriggerContext>\n );\n}",".userInfo {\n display: flex;\n flex-direction: column;\n gap: var(--ds-spacing-1);\n padding: var(--ds-spacing-2) var(--ds-spacing-3);\n}\n\n.userName {\n font-size: var(--ds-font-size-sm);\n font-weight: var(--ds-font-weight-medium);\n color: var(--ds-color-neutral-text-default);\n}\n\n.userEmail {\n font-size: var(--ds-font-size-xs);\n color: var(--ds-color-neutral-text-subtle);\n}\n\n.menuButton {\n background-color: var(--ds-color-neutral-base-default);\n}\n\n.devContainer {\n display: flex;\n gap: var(--ds-spacing-4);\n padding: var(--ds-spacing-2);\n}\n\n.zoneSection {\n flex: 1;\n min-width: 12rem;\n}\n\n.zoneTitle {\n font-weight: 600;\n padding: var(--ds-spacing-2);\n color: var(--ds-color-neutral-text-default);\n border-bottom: 1px solid var(--ds-color-neutral-border-subtle);\n margin-bottom: var(--ds-spacing-2);\n text-transform: capitalize;\n}\n",".header {\n background-color: var(--ds-color-accent-surface-tinted);\n border-bottom: 1px solid var(--ds-color-neutral-border-subtle);\n position: sticky;\n top: 0;\n z-index: 100;\n}\n\n.headerContainer {\n max-width: 90rem;\n margin: 0 auto;\n padding: 0 var(--ds-size-30);\n}\n\n.topBarContainer {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 1.25rem 0;\n}\n\n.logo {\n margin: 0;\n color: var(--ds-color-neutral-text-default);\n white-space: nowrap;\n display: flex;\n align-items: center;\n min-height: inherit;\n}\n\n.actionsContainer {\n display: flex;\n align-items: stretch;\n gap: var(--ds-size-9);\n min-height: inherit;\n}\n\n.searchInput {\n min-width: 12.5rem;\n display: flex;\n align-items: center;\n}\n\n@media (max-width: 768px) {\n .container {\n padding: 0 var(--ds-spacing-4);\n }\n\n .topBar {\n flex-wrap: wrap;\n padding: var(--ds-spacing-4) 0;\n }\n\n .actions {\n order: 3;\n width: 100%;\n flex-direction: column;\n gap: var(--ds-spacing-3);\n }\n\n .searchInput {\n width: 100%;\n min-width: auto;\n }\n\n .menuButton {\n width: 100%;\n justify-content: center;\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}",".footer {\n background-color: var(--ds-color-neutral-surface-subtle);\n border-top: 1px solid var(--ds-color-neutral-border-subtle);\n margin-top: auto;\n}\n\n.container {\n max-width: 1440px;\n margin: 0 auto;\n padding: var(--ds-spacing-6) var(--ds-spacing-4);\n}\n\n.content {\n display: flex;\n justify-content: space-between;\n align-items: center;\n gap: var(--ds-spacing-4);\n flex-wrap: wrap;\n}\n\n@media (max-width: 768px) {\n .content {\n flex-direction: column;\n align-items: flex-start;\n }\n\n\n}",".root {\n display: flex;\n flex-direction: column;\n min-height: 100vh;\n}\n\n.main {\n flex: 1;\n}","import { create, StateCreator } from 'zustand';\nimport { persist, createJSONStorage } from 'zustand/middleware';\n\nexport type Theme = 'light' | 'dark' | 'system';\n\nexport type GlobalState = {\n user?: { id: string; name?: string } | null;\n theme: Theme;\n locale: string;\n setUser: (user: GlobalState['user']) => void;\n setTheme: (theme: Theme) => void;\n setLocale: (locale: string) => 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 setUser: (user) => set({ user }),\n setTheme: (theme) => {\n set({ theme });\n if (typeof document !== 'undefined') {\n document.documentElement.setAttribute('data-color-scheme', theme);\n }\n },\n setLocale: (locale) => set({ locale }),\n initialize: () => {\n if (typeof document !== 'undefined') {\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 })\n);\n"],"mappings":"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","names":["import_react","import_clsx","import_designsystemet_react","import_clsx","breadcrumbs","link","currentLink","_a","clsx","import_designsystemet_react","userInfo","userName","userEmail","menuButton","devContainer","zoneSection","zoneTitle","import_jsx_runtime","Link","header","headerContainer","topBarContainer","logo","actionsContainer","searchInput","container","topBar","actions","menuButton","import_jsx_runtime","clsx","import_designsystemet_react","import_clsx","footer","container","content","import_jsx_runtime","clsx","root","main","import_jsx_runtime","clsx"]}
|
package/dist/index.mjs
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
1
3
|
// src/components/RootLayout/RootLayout.tsx
|
|
2
4
|
import { useEffect } from "react";
|
|
3
5
|
import clsx4 from "clsx";
|
|
@@ -248,13 +250,12 @@ var GlobalHeader_default = {
|
|
|
248
250
|
var logo_default = "./logo-X7RC63NT.svg";
|
|
249
251
|
|
|
250
252
|
// src/components/GlobalHeader/GlobalHeader.tsx
|
|
251
|
-
import Image from "next/image";
|
|
252
253
|
import { jsx as jsx3, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
253
254
|
function GlobalHeader({ className, zone }) {
|
|
254
255
|
const [searchValue, setSearchValue] = useState("");
|
|
255
256
|
return /* @__PURE__ */ jsx3("header", { className: clsx2(GlobalHeader_default.header, className), children: /* @__PURE__ */ jsxs2("div", { className: GlobalHeader_default.headerContainer, children: [
|
|
256
257
|
/* @__PURE__ */ jsxs2("div", { className: GlobalHeader_default.topBarContainer, children: [
|
|
257
|
-
/* @__PURE__ */ jsx3(Link2, { href: "https://www.statsbygg.no", children: /* @__PURE__ */ jsx3(
|
|
258
|
+
/* @__PURE__ */ jsx3(Link2, { href: "https://www.statsbygg.no", children: /* @__PURE__ */ jsx3("img", { src: logo_default, alt: "Logo", className: GlobalHeader_default.logo }) }),
|
|
258
259
|
/* @__PURE__ */ jsxs2("div", { className: GlobalHeader_default.actionsContainer, children: [
|
|
259
260
|
/* @__PURE__ */ jsx3(
|
|
260
261
|
Textfield,
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/components/RootLayout/RootLayout.tsx","../src/components/GlobalHeader/GlobalHeader.tsx","../src/components/Breadcrumbs/Breadcrumbs.tsx","../src/components/Breadcrumbs/Breadcrumbs.module.css","../src/routes.ts","../src/components/MenuButton/MenuButton.tsx","../src/components/MenuButton/MenuButton.module.css","../src/components/GlobalHeader/GlobalHeader.module.css","../src/components/GlobalFooter/GlobalFooter.tsx","../src/components/GlobalFooter/GlobalFooter.module.css","../src/components/RootLayout/RootLayout.module.css","../src/store/globalState.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';\n\nexport function RootLayout({\n children,\n zone, \n className,\n}: RootLayoutProps) {\n const initialize = useGlobalStore((state) => state.initialize);\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, className)} data-zone={zone}>\n <GlobalHeader zone={zone}/>\n <main className={styles.main}>{children}</main>\n <GlobalFooter />\n </div>\n );\n}\n","'use client';\n\nimport { useState } from 'react';\nimport { Link, Textfield } 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 logo from '../../logo.svg'; \nimport Image from 'next/image';\n\nexport function GlobalHeader({ className, zone }: GlobalHeaderProps) {\n const [searchValue, setSearchValue] = useState('');\n\n return (\n <header className={clsx(styles.header, className)}>\n <div className={styles.headerContainer}>\n <div className={styles.topBarContainer}>\n <Link href=\"https://www.statsbygg.no\">\n <Image src={logo} alt=\"Logo\" className={styles.logo} />\n </Link>\n <div className={styles.actionsContainer}>\n <Textfield\n value={searchValue}\n onChange={(e) => setSearchValue(e.target.value)}\n placeholder=\"Søk...\"\n className={styles.searchInput}\n aria-label=\"Søk\"\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';\n\nexport function SbBreadcrumbs({ className, zone }: BreadcrumbsProps) {\n const pathname = usePathname();\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 = getBreadcrumbs(zone, fullPath);\n\n if (breadcrumbs.length <= 1) {\n return null;\n }\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 = 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}",".breadcrumbs {\n --dsc-breadcrumbs-color: var(--ds-color-text-default);\n padding: 2.5rem 0 0 0;\n}\n\n.link {\n text-decoration: underline;\n text-underline-offset: 2px;\n color: var(--ds-color-text-default);\n}\n\n.link:hover \n.link:visited{\n color: var(--ds-color-text-default);\n}\n\n.currentLink {\n text-decoration: none;\n font-weight: 500;\n pointer-events: none;\n color: var(--ds-color-text-default);\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}","'use client';\n\nimport Link from 'next/link';\nimport { Dropdown } from '@digdir/designsystemet-react';\nimport { Menu } from 'lucide-react';\nimport { getZoneMenuRoutes, getAllZones, transformHrefForZone } from '@/routes';\nimport type { MenuButtonProps } from './MenuButton.types';\nimport styles from './MenuButton.module.css';\n\nexport function MenuButton({ zone }: MenuButtonProps) {\n const isDev = process.env.NODE_ENV === 'development';\n // TODO: Temporary here. Should come from env or something\n const prodUrl = 'https://www.statsbygg.no';\n const allZones = getAllZones();\n\n return (\n <Dropdown.TriggerContext>\n <Dropdown.Trigger asChild className={styles.menuButton}>\n <Menu size={20} aria-hidden />\n Meny\n </Dropdown.Trigger>\n <Dropdown>\n {isDev ? (\n <div className={styles.devContainer}>\n {allZones.map((z) => {\n const routes = getZoneMenuRoutes(z);\n return (\n <div key={z} className={styles.zoneSection}>\n <div className={styles.zoneTitle}>{z}</div>\n <Dropdown.List>\n {routes.map((r) => (\n <Dropdown.Item key={`${r.zone}:${r.path}`}>\n <Link href={transformHrefForZone(r.path, zone, { isDev, prodUrl })}>\n {r.label}\n </Link>\n </Dropdown.Item>\n ))}\n </Dropdown.List>\n </div>\n );\n })}\n </div>\n ) : (\n <Dropdown.List>\n {getZoneMenuRoutes(zone).map((r) => (\n <Dropdown.Item key={`${r.zone}:${r.path}`}>\n <Link href={transformHrefForZone(r.path, zone, { isDev, prodUrl })}>\n {r.label}\n </Link>\n </Dropdown.Item>\n ))}\n </Dropdown.List>\n )}\n </Dropdown>\n </Dropdown.TriggerContext>\n );\n}",".userInfo {\n display: flex;\n flex-direction: column;\n gap: var(--ds-spacing-1);\n padding: var(--ds-spacing-2) var(--ds-spacing-3);\n}\n\n.userName {\n font-size: var(--ds-font-size-sm);\n font-weight: var(--ds-font-weight-medium);\n color: var(--ds-color-neutral-text-default);\n}\n\n.userEmail {\n font-size: var(--ds-font-size-xs);\n color: var(--ds-color-neutral-text-subtle);\n}\n\n.menuButton {\n background-color: var(--ds-color-neutral-base-default);\n}\n\n.devContainer {\n display: flex;\n gap: var(--ds-spacing-4);\n padding: var(--ds-spacing-2);\n}\n\n.zoneSection {\n flex: 1;\n min-width: 12rem;\n}\n\n.zoneTitle {\n font-weight: 600;\n padding: var(--ds-spacing-2);\n color: var(--ds-color-neutral-text-default);\n border-bottom: 1px solid var(--ds-color-neutral-border-subtle);\n margin-bottom: var(--ds-spacing-2);\n text-transform: capitalize;\n}\n",".header {\n background-color: var(--ds-color-accent-surface-tinted);\n border-bottom: 1px solid var(--ds-color-neutral-border-subtle);\n position: sticky;\n top: 0;\n z-index: 100;\n}\n\n.headerContainer {\n max-width: 90rem;\n margin: 0 auto;\n padding: 0 var(--ds-size-30);\n}\n\n.topBarContainer {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 1.25rem 0;\n}\n\n.logo {\n margin: 0;\n color: var(--ds-color-neutral-text-default);\n white-space: nowrap;\n display: flex;\n align-items: center;\n min-height: inherit;\n}\n\n.actionsContainer {\n display: flex;\n align-items: stretch;\n gap: var(--ds-size-9);\n min-height: inherit;\n}\n\n.searchInput {\n min-width: 12.5rem;\n display: flex;\n align-items: center;\n}\n\n@media (max-width: 768px) {\n .container {\n padding: 0 var(--ds-spacing-4);\n }\n\n .topBar {\n flex-wrap: wrap;\n padding: var(--ds-spacing-4) 0;\n }\n\n .actions {\n order: 3;\n width: 100%;\n flex-direction: column;\n gap: var(--ds-spacing-3);\n }\n\n .searchInput {\n width: 100%;\n min-width: auto;\n }\n\n .menuButton {\n width: 100%;\n justify-content: center;\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}",".footer {\n background-color: var(--ds-color-neutral-surface-subtle);\n border-top: 1px solid var(--ds-color-neutral-border-subtle);\n margin-top: auto;\n}\n\n.container {\n max-width: 1440px;\n margin: 0 auto;\n padding: var(--ds-spacing-6) var(--ds-spacing-4);\n}\n\n.content {\n display: flex;\n justify-content: space-between;\n align-items: center;\n gap: var(--ds-spacing-4);\n flex-wrap: wrap;\n}\n\n@media (max-width: 768px) {\n .content {\n flex-direction: column;\n align-items: flex-start;\n }\n\n\n}",".root {\n display: flex;\n flex-direction: column;\n min-height: 100vh;\n}\n\n.main {\n flex: 1;\n}","import { create, StateCreator } from 'zustand';\nimport { persist, createJSONStorage } from 'zustand/middleware';\n\nexport type Theme = 'light' | 'dark' | 'system';\n\nexport type GlobalState = {\n user?: { id: string; name?: string } | null;\n theme: Theme;\n locale: string;\n setUser: (user: GlobalState['user']) => void;\n setTheme: (theme: Theme) => void;\n setLocale: (locale: string) => 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 setUser: (user) => set({ user }),\n setTheme: (theme) => {\n set({ theme });\n if (typeof document !== 'undefined') {\n document.documentElement.setAttribute('data-color-scheme', theme);\n }\n },\n setLocale: (locale) => set({ locale }),\n initialize: () => {\n if (typeof document !== 'undefined') {\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 })\n);\n"],"mappings":"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","names":["clsx","Link","clsx","breadcrumbs","link","currentLink","_a","userInfo","userName","userEmail","menuButton","devContainer","zoneSection","zoneTitle","jsx","header","headerContainer","topBarContainer","logo","actionsContainer","searchInput","container","topBar","actions","menuButton","jsx","jsxs","clsx","Link","clsx","footer","container","content","jsx","clsx","root","main","jsx","jsxs","clsx"]}
|
|
1
|
+
{"version":3,"sources":["../src/components/RootLayout/RootLayout.tsx","../src/components/GlobalHeader/GlobalHeader.tsx","../src/components/Breadcrumbs/Breadcrumbs.tsx","../src/components/Breadcrumbs/Breadcrumbs.module.css","../src/routes.ts","../src/components/MenuButton/MenuButton.tsx","../src/components/MenuButton/MenuButton.module.css","../src/components/GlobalHeader/GlobalHeader.module.css","../src/components/GlobalFooter/GlobalFooter.tsx","../src/components/GlobalFooter/GlobalFooter.module.css","../src/components/RootLayout/RootLayout.module.css","../src/store/globalState.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';\n\nexport function RootLayout({\n children,\n zone, \n className,\n}: RootLayoutProps) {\n const initialize = useGlobalStore((state) => state.initialize);\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, className)} data-zone={zone}>\n <GlobalHeader zone={zone}/>\n <main className={styles.main}>{children}</main>\n <GlobalFooter />\n </div>\n );\n}\n","'use client';\n\nimport { useState } from 'react';\nimport { Link, Textfield } 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 logo from '../../logo.svg'; \n\nexport function GlobalHeader({ className, zone }: GlobalHeaderProps) {\n const [searchValue, setSearchValue] = useState('');\n\n return (\n <header className={clsx(styles.header, className)}>\n <div className={styles.headerContainer}>\n <div className={styles.topBarContainer}>\n <Link href=\"https://www.statsbygg.no\">\n <img src={logo} alt=\"Logo\" className={styles.logo} />\n </Link>\n <div className={styles.actionsContainer}>\n <Textfield\n value={searchValue}\n onChange={(e) => setSearchValue(e.target.value)}\n placeholder=\"Søk...\"\n className={styles.searchInput}\n aria-label=\"Søk\"\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';\n\nexport function SbBreadcrumbs({ className, zone }: BreadcrumbsProps) {\n const pathname = usePathname();\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 = getBreadcrumbs(zone, fullPath);\n\n if (breadcrumbs.length <= 1) {\n return null;\n }\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 = 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}",".breadcrumbs {\n --dsc-breadcrumbs-color: var(--ds-color-text-default);\n padding: 2.5rem 0 0 0;\n}\n\n.link {\n text-decoration: underline;\n text-underline-offset: 2px;\n color: var(--ds-color-text-default);\n}\n\n.link:hover \n.link:visited{\n color: var(--ds-color-text-default);\n}\n\n.currentLink {\n text-decoration: none;\n font-weight: 500;\n pointer-events: none;\n color: var(--ds-color-text-default);\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}","'use client';\n\nimport Link from 'next/link';\nimport { Dropdown } from '@digdir/designsystemet-react';\nimport { Menu } from 'lucide-react';\nimport { getZoneMenuRoutes, getAllZones, transformHrefForZone } from '@/routes';\nimport type { MenuButtonProps } from './MenuButton.types';\nimport styles from './MenuButton.module.css';\n\nexport function MenuButton({ zone }: MenuButtonProps) {\n const isDev = process.env.NODE_ENV === 'development';\n // TODO: Temporary here. Should come from env or something\n const prodUrl = 'https://www.statsbygg.no';\n const allZones = getAllZones();\n\n return (\n <Dropdown.TriggerContext>\n <Dropdown.Trigger asChild className={styles.menuButton}>\n <Menu size={20} aria-hidden />\n Meny\n </Dropdown.Trigger>\n <Dropdown>\n {isDev ? (\n <div className={styles.devContainer}>\n {allZones.map((z) => {\n const routes = getZoneMenuRoutes(z);\n return (\n <div key={z} className={styles.zoneSection}>\n <div className={styles.zoneTitle}>{z}</div>\n <Dropdown.List>\n {routes.map((r) => (\n <Dropdown.Item key={`${r.zone}:${r.path}`}>\n <Link href={transformHrefForZone(r.path, zone, { isDev, prodUrl })}>\n {r.label}\n </Link>\n </Dropdown.Item>\n ))}\n </Dropdown.List>\n </div>\n );\n })}\n </div>\n ) : (\n <Dropdown.List>\n {getZoneMenuRoutes(zone).map((r) => (\n <Dropdown.Item key={`${r.zone}:${r.path}`}>\n <Link href={transformHrefForZone(r.path, zone, { isDev, prodUrl })}>\n {r.label}\n </Link>\n </Dropdown.Item>\n ))}\n </Dropdown.List>\n )}\n </Dropdown>\n </Dropdown.TriggerContext>\n );\n}",".userInfo {\n display: flex;\n flex-direction: column;\n gap: var(--ds-spacing-1);\n padding: var(--ds-spacing-2) var(--ds-spacing-3);\n}\n\n.userName {\n font-size: var(--ds-font-size-sm);\n font-weight: var(--ds-font-weight-medium);\n color: var(--ds-color-neutral-text-default);\n}\n\n.userEmail {\n font-size: var(--ds-font-size-xs);\n color: var(--ds-color-neutral-text-subtle);\n}\n\n.menuButton {\n background-color: var(--ds-color-neutral-base-default);\n}\n\n.devContainer {\n display: flex;\n gap: var(--ds-spacing-4);\n padding: var(--ds-spacing-2);\n}\n\n.zoneSection {\n flex: 1;\n min-width: 12rem;\n}\n\n.zoneTitle {\n font-weight: 600;\n padding: var(--ds-spacing-2);\n color: var(--ds-color-neutral-text-default);\n border-bottom: 1px solid var(--ds-color-neutral-border-subtle);\n margin-bottom: var(--ds-spacing-2);\n text-transform: capitalize;\n}\n",".header {\n background-color: var(--ds-color-accent-surface-tinted);\n border-bottom: 1px solid var(--ds-color-neutral-border-subtle);\n position: sticky;\n top: 0;\n z-index: 100;\n}\n\n.headerContainer {\n max-width: 90rem;\n margin: 0 auto;\n padding: 0 var(--ds-size-30);\n}\n\n.topBarContainer {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 1.25rem 0;\n}\n\n.logo {\n margin: 0;\n color: var(--ds-color-neutral-text-default);\n white-space: nowrap;\n display: flex;\n align-items: center;\n min-height: inherit;\n}\n\n.actionsContainer {\n display: flex;\n align-items: stretch;\n gap: var(--ds-size-9);\n min-height: inherit;\n}\n\n.searchInput {\n min-width: 12.5rem;\n display: flex;\n align-items: center;\n}\n\n@media (max-width: 768px) {\n .container {\n padding: 0 var(--ds-spacing-4);\n }\n\n .topBar {\n flex-wrap: wrap;\n padding: var(--ds-spacing-4) 0;\n }\n\n .actions {\n order: 3;\n width: 100%;\n flex-direction: column;\n gap: var(--ds-spacing-3);\n }\n\n .searchInput {\n width: 100%;\n min-width: auto;\n }\n\n .menuButton {\n width: 100%;\n justify-content: center;\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}",".footer {\n background-color: var(--ds-color-neutral-surface-subtle);\n border-top: 1px solid var(--ds-color-neutral-border-subtle);\n margin-top: auto;\n}\n\n.container {\n max-width: 1440px;\n margin: 0 auto;\n padding: var(--ds-spacing-6) var(--ds-spacing-4);\n}\n\n.content {\n display: flex;\n justify-content: space-between;\n align-items: center;\n gap: var(--ds-spacing-4);\n flex-wrap: wrap;\n}\n\n@media (max-width: 768px) {\n .content {\n flex-direction: column;\n align-items: flex-start;\n }\n\n\n}",".root {\n display: flex;\n flex-direction: column;\n min-height: 100vh;\n}\n\n.main {\n flex: 1;\n}","import { create, StateCreator } from 'zustand';\nimport { persist, createJSONStorage } from 'zustand/middleware';\n\nexport type Theme = 'light' | 'dark' | 'system';\n\nexport type GlobalState = {\n user?: { id: string; name?: string } | null;\n theme: Theme;\n locale: string;\n setUser: (user: GlobalState['user']) => void;\n setTheme: (theme: Theme) => void;\n setLocale: (locale: string) => 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 setUser: (user) => set({ user }),\n setTheme: (theme) => {\n set({ theme });\n if (typeof document !== 'undefined') {\n document.documentElement.setAttribute('data-color-scheme', theme);\n }\n },\n setLocale: (locale) => set({ locale }),\n initialize: () => {\n if (typeof document !== 'undefined') {\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 })\n);\n"],"mappings":"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","names":["clsx","Link","clsx","breadcrumbs","link","currentLink","_a","userInfo","userName","userEmail","menuButton","devContainer","zoneSection","zoneTitle","jsx","header","headerContainer","topBarContainer","logo","actionsContainer","searchInput","container","topBar","actions","menuButton","jsx","jsxs","clsx","Link","clsx","footer","container","content","jsx","clsx","root","main","jsx","jsxs","clsx"]}
|