@broberg/app-shell 0.2.0 → 0.2.2
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/README.md +3 -2
- package/css/app-shell.css +8 -1
- package/dist/preact.cjs +1 -1
- package/dist/preact.cjs.map +1 -1
- package/dist/preact.d.cts +6 -1
- package/dist/preact.d.ts +6 -1
- package/dist/preact.js +1 -1
- package/dist/preact.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -61,8 +61,9 @@ hamburger) are gone; `Sidebar` no longer takes `onToggleCollapse`.
|
|
|
61
61
|
site-header. Desktop: folds the sidebar, remembered. Phone: opens the drawer.
|
|
62
62
|
`aria-expanded` and `aria-label` follow the state.
|
|
63
63
|
- **The title** is `title`, else the label of the active nav item (a sub-item
|
|
64
|
-
beats its parent). No title → no empty `<h1>`.
|
|
65
|
-
|
|
64
|
+
beats its parent). No title → no empty `<h1>`. **0.2.1:** `PageHeader.title`
|
|
65
|
+
is optional, so a page keeps its description and actions under the content
|
|
66
|
+
header without repeating the title (dashboard-01 has the title only up top).
|
|
66
67
|
- **Sub-items:** `NavItem.children` (one level). The parent is a button with a
|
|
67
68
|
chevron that turns 90° (`sidebar-item-<id>-toggle`, `aria-expanded`); the
|
|
68
69
|
children sit indented behind a thin rule. Open items are remembered; the
|
package/css/app-shell.css
CHANGED
|
@@ -24,7 +24,10 @@
|
|
|
24
24
|
color: var(--fg);
|
|
25
25
|
}
|
|
26
26
|
.bas-root *, .bas-root *::before, .bas-root *::after { box-sizing: border-box; }
|
|
27
|
-
|
|
27
|
+
/* Zero specificity on purpose: `.bas-root button` (0,1,1) beat `.bas-item`'s
|
|
28
|
+
* 13px (0,1,0), so an item with children — a <button> — came out in the page's
|
|
29
|
+
* font size next to its <a> siblings (appkit, Lens 8ce4cc94). */
|
|
30
|
+
:where(.bas-root button) { font: inherit; }
|
|
28
31
|
|
|
29
32
|
/* ── top bar ── */
|
|
30
33
|
.bas-topbar {
|
|
@@ -52,6 +55,10 @@
|
|
|
52
55
|
|
|
53
56
|
/* ── sidebar ── */
|
|
54
57
|
.bas-sidebar {
|
|
58
|
+
/* sticky makes its own stacking context, so the rail's flyout can only rise
|
|
59
|
+
* as high as the sidebar does; without this <main> paints over it and takes
|
|
60
|
+
* its clicks (appkit, Lens 839394b1). Below the top bar (50). */
|
|
61
|
+
z-index: 20;
|
|
55
62
|
flex: 0 0 240px; width: 240px;
|
|
56
63
|
position: sticky; top: var(--bas-top); align-self: flex-start;
|
|
57
64
|
height: calc(100dvh - var(--bas-top));
|
package/dist/preact.cjs
CHANGED
|
@@ -728,7 +728,7 @@ function PageHeader(p) {
|
|
|
728
728
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { class: "bas-pagehead", "data-testid": "page-header", children: [
|
|
729
729
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { class: "bas-pagehead__text", children: [
|
|
730
730
|
p.eyebrow ? /* @__PURE__ */ jsxRuntime.jsx("div", { class: "bas-pagehead__eyebrow", children: p.eyebrow }) : null,
|
|
731
|
-
/* @__PURE__ */ jsxRuntime.jsx("h1", { class: "bas-pagehead__title", children: p.title }),
|
|
731
|
+
p.title != null && p.title !== "" ? /* @__PURE__ */ jsxRuntime.jsx("h1", { class: "bas-pagehead__title", children: p.title }) : null,
|
|
732
732
|
p.description ? /* @__PURE__ */ jsxRuntime.jsx("p", { class: "bas-pagehead__desc", children: p.description }) : null
|
|
733
733
|
] }),
|
|
734
734
|
p.actions ? /* @__PURE__ */ jsxRuntime.jsx("div", { class: "bas-pagehead__actions", children: p.actions }) : null
|
package/dist/preact.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/preact.tsx"],"names":["useState","useEffect","jsx","jsxs","Fragment","useRef","shell","useMemo","createBellShell","getPreference","getPalette","getSurfaces","getBackdrop","onThemeChange","onPaletteChange","onSurfacesChange","onBackdropChange","setPreference","PALETTES","PALETTE_LABELS","setPalette","setSurfaces","setBackdrop"],"mappings":"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","file":"preact.cjs","sourcesContent":["// @broberg/app-shell — the framework-free core of the fleet's app shell (F092).\n//\n// The shell every app in the fleet had been copying: sidebar + top bar +\n// notification bell + user menu. cardmem and trail each had one (\"ported from\n// trail\"), and helpdesk and the appkit starter would have made the third and\n// fourth. This file holds what does not depend on a framework: the navigation\n// data model, the notification contract and its sources, and the small rules\n// both the Preact and React parts must agree on.\n//\n// Christian, 4 Oct 2026: notifications are a STANDARD part of the template, not\n// an optional slot — so the contract and a default source live here, and a new\n// app gets a working notification centre by pointing one URL at its backend.\n\n// ── Navigation ─────────────────────────────────────────────────────────────\n\n/** One sidebar entry. `icon` is whatever your framework renders (an element). */\nexport interface NavItem<Icon = unknown> {\n id: string;\n label: string;\n href: string;\n icon?: Icon;\n /** A count shown on the item (99+ above 99). 0/undefined shows nothing. */\n badge?: number;\n /**\n * Sub-items, ONE level (F092.5). An item with children is a toggle that opens\n * and closes them, not a link; its own `href` is used only to decide whether\n * it is on the current path.\n */\n children?: NavItem<Icon>[];\n}\nexport interface NavGroup<Icon = unknown> {\n label: string;\n items: NavItem<Icon>[];\n}\n\n/**\n * Is this item the current page? Exact match for \"/\", otherwise the path is the\n * item or below it (\"/board/123\" is on \"/board\", \"/boardroom\" is not).\n */\nexport function isActivePath(href: string, currentPath: string): boolean {\n const path = (currentPath.split(/[?#]/)[0] || \"/\").replace(/\\/+$/, \"\") || \"/\";\n const target = (href.split(/[?#]/)[0] || \"/\").replace(/\\/+$/, \"\") || \"/\";\n if (target === \"/\") return path === \"/\";\n return path === target || path.startsWith(target + \"/\");\n}\n\n/**\n * A notification's `navigate` is SERVER DATA, and it ends in `location.assign`.\n * `javascript:` there runs code in the app, so only a same-site path or an\n * http(s) URL is followed; anything else returns null and the row just closes.\n */\nexport function safeNavigate(target: string | null | undefined): string | null {\n if (typeof target !== \"string\") return null;\n const t = target.trim();\n if (t.startsWith(\"/\") && !t.startsWith(\"//\") && !t.startsWith(\"/\\\\\")) return t;\n try {\n const u = new URL(t);\n return u.protocol === \"https:\" || u.protocol === \"http:\" ? u.href : null;\n } catch {\n return null;\n }\n}\n\n/**\n * The label of the nav item the user is on, for the content header (F092.4).\n * Sub-items count, and the most specific match wins: on \"/models/genesis\" a\n * \"Genesis\" child beats its \"Models\" parent.\n */\nexport function activeNavLabel<Icon>(\n groups: NavGroup<Icon>[],\n footer: NavItem<Icon>[] | undefined,\n currentPath: string,\n): string | undefined {\n let best: { label: string; len: number } | undefined;\n const visit = (it: NavItem<Icon>) => {\n if (it.href && isActivePath(it.href, currentPath)) {\n const len = it.href.length;\n if (!best || len > best.len) best = { label: it.label, len };\n }\n it.children?.forEach(visit);\n };\n for (const g of groups) g.items.forEach(visit);\n footer?.forEach(visit);\n return best?.label;\n}\n\n/** \"99+\" above 99, nothing for 0 or less. */\nexport function badgeLabel(n: number | undefined): string | null {\n if (!n || n <= 0) return null;\n return n > 99 ? \"99+\" : String(n);\n}\n\n// ── Persisted UI state ─────────────────────────────────────────────────────\n\n/** Read a boolean flag from localStorage; storage errors read as `fallback`. */\nexport function readFlag(key: string, fallback: boolean): boolean {\n try {\n const v = typeof localStorage === \"undefined\" ? null : localStorage.getItem(key);\n return v === null ? fallback : v === \"1\";\n } catch {\n return fallback;\n }\n}\nexport function writeFlag(key: string, value: boolean): void {\n try {\n if (typeof localStorage !== \"undefined\") localStorage.setItem(key, value ? \"1\" : \"0\");\n } catch {\n /* private mode / quota: the UI still works, it just does not remember */\n }\n}\nexport function readSet(key: string): Set<string> {\n try {\n const raw = typeof localStorage === \"undefined\" ? null : localStorage.getItem(key);\n const v = raw ? (JSON.parse(raw) as unknown) : [];\n return new Set(Array.isArray(v) ? v.filter((x): x is string => typeof x === \"string\") : []);\n } catch {\n return new Set();\n }\n}\nexport function writeSet(key: string, value: Set<string>): void {\n try {\n if (typeof localStorage !== \"undefined\") localStorage.setItem(key, JSON.stringify([...value]));\n } catch {\n /* see writeFlag */\n }\n}\n\n// ── Avatar ─────────────────────────────────────────────────────────────────\n\n/**\n * Two initials for the avatar fallback: first letter of the first and the last\n * word, upper-cased. One word gives one letter; nothing gives \"?\".\n *\n * There is deliberately no Gravatar here (owner decision D-1dc849): the avatar\n * is the Broberg ID `picture`, and without one, initials. Gravatar would send a\n * hash of the user's email to a US service on every render.\n */\nexport function initials(name: string | undefined, email?: string): string {\n const source = (name ?? \"\").trim() || (email ?? \"\").split(\"@\")[0] || \"\";\n const words = source.split(/[\\s._-]+/).filter(Boolean);\n if (words.length === 0) return \"?\";\n const first = words[0]![0] ?? \"\";\n const last = words.length > 1 ? words[words.length - 1]![0] ?? \"\" : \"\";\n return (first + last).toUpperCase() || \"?\";\n}\n\n// ── Notifications ──────────────────────────────────────────────────────────\n//\n// REUSE, NOT A SECOND CONTRACT. The fleet already agreed the notification shape\n// in @broberg/notifications (F074): `NotificationRow` — the same field names\n// @broberg/webpush sends, end to end — and the server core that owns the ONE\n// counting rule. The shell's bell renders that row and drives its panel with\n// that package's `createBellShell`, so a server built on `createNotifications`\n// and this bell speak the same language without an adapter.\n//\n// Christian, 4 Oct 2026: notifications are a STANDARD part of the template. So\n// a source, and a default one, ship here: point one URL at your backend.\n\nimport type { NotificationRow } from \"@broberg/notifications/types\";\nexport type { NotificationRow } from \"@broberg/notifications/types\";\n\n/** Where the bell gets its data. Swap it to point at any backend. */\nexport interface NotificationSource {\n /** The rows to show (newest first). */\n loadRows(): Promise<NotificationRow[]>;\n /** THE count — your server's, which may exclude muted kinds (F074's counting rule). */\n countUnseen(): Promise<number>;\n /** Returns the ids that actually transitioned to seen. */\n markSeen(ids: readonly string[]): Promise<string[]>;\n markAllSeen(): Promise<string[]>;\n /** Called with a callback that re-counts; return an unsubscribe. Optional. */\n subscribe?(onChange: () => void): () => void;\n}\n\n/**\n * The default source: a URL on your own backend, shaped after\n * @broberg/notifications' server core so `createNotifications` sits right\n * behind it.\n *\n * GET {url} → { items: NotificationRow[], unseen: number }\n * POST {url}/seen { ids: string[] } → { clearedIds: string[], count: number }\n * POST {url}/seen-all → { clearedIds: string[], count: number }\n *\n * It re-counts when the window regains focus or the tab becomes visible, and on\n * a timer (default 60 s). A failed GET THROWS — the bell shows «could not\n * load», never an empty list: \"could not fetch\" and \"nothing new\" must not look\n * the same.\n */\nexport function createFetchNotificationSource(opts: {\n url: string;\n fetch?: typeof fetch;\n /** Re-count interval in ms. 0 turns it off. Default 60 000. */\n pollMs?: number;\n credentials?: RequestCredentials;\n}): NotificationSource {\n const base = opts.url.replace(/\\/+$/, \"\");\n const doFetch = (input: string, init?: RequestInit) =>\n (opts.fetch ?? fetch)(input, { credentials: opts.credentials ?? \"include\", ...init });\n const get = async (): Promise<{ items: NotificationRow[]; unseen: number }> => {\n const res = await doFetch(base, { headers: { accept: \"application/json\" } });\n if (!res.ok) throw new Error(`HTTP ${res.status}`);\n const body = (await res.json().catch(() => null)) as { items?: unknown; unseen?: unknown } | null;\n if (!body || !Array.isArray(body.items)) throw new Error(\"response has no items array\");\n const items = body.items as NotificationRow[];\n const unseen = typeof body.unseen === \"number\" ? body.unseen : items.filter((n) => n.seenAt == null).length;\n return { items, unseen };\n };\n const post = async (path: string, body?: unknown): Promise<string[]> => {\n const res = await doFetch(`${base}${path}`, {\n method: \"POST\",\n headers: body === undefined ? undefined : { \"content-type\": \"application/json\" },\n body: body === undefined ? undefined : JSON.stringify(body),\n });\n if (!res.ok) throw new Error(`HTTP ${res.status}`);\n const r = (await res.json().catch(() => ({}))) as { clearedIds?: unknown };\n return Array.isArray(r.clearedIds) ? (r.clearedIds as string[]) : [];\n };\n return {\n loadRows: async () => (await get()).items,\n countUnseen: async () => (await get()).unseen,\n markSeen: (ids) => post(\"/seen\", { ids }),\n markAllSeen: () => post(\"/seen-all\"),\n subscribe(onChange) {\n if (typeof window === \"undefined\") return () => {};\n const onVisible = () => {\n if (document.visibilityState === \"visible\") onChange();\n };\n window.addEventListener(\"focus\", onChange);\n document.addEventListener(\"visibilitychange\", onVisible);\n const ms = opts.pollMs ?? 60_000;\n const timer = ms > 0 ? setInterval(onChange, ms) : null;\n return () => {\n window.removeEventListener(\"focus\", onChange);\n document.removeEventListener(\"visibilitychange\", onVisible);\n if (timer) clearInterval(timer);\n };\n },\n };\n}\n\n/** An in-memory source for demos and tests. */\nexport function createMemoryNotificationSource(initial: NotificationRow[] = []): NotificationSource & {\n push(n: NotificationRow): void;\n rows(): NotificationRow[];\n} {\n let rows = initial.map((n) => ({ ...n }));\n const listeners = new Set<() => void>();\n const emit = () => listeners.forEach((l) => l());\n const mark = (pred: (n: NotificationRow) => boolean): string[] => {\n const now = Date.now();\n const cleared: string[] = [];\n rows = rows.map((n) => {\n if (n.seenAt == null && pred(n)) {\n cleared.push(n.id);\n return { ...n, seenAt: now };\n }\n return n;\n });\n if (cleared.length) emit();\n return cleared;\n };\n return {\n loadRows: async () => rows.map((n) => ({ ...n })),\n countUnseen: async () => rows.filter((n) => n.seenAt == null).length,\n markSeen: async (ids) => mark((n) => ids.includes(n.id)),\n markAllSeen: async () => mark(() => true),\n subscribe(onChange) {\n listeners.add(onChange);\n return () => listeners.delete(onChange);\n },\n push(n) {\n rows = [n, ...rows];\n emit();\n },\n rows: () => rows.map((n) => ({ ...n })),\n };\n}\n\n/** \"nu\", \"5 min\", \"3 t\", \"i går\", \"4 d\" (da) or the English equivalents. */\nexport function relativeTime(ts: string | number, lang: \"da\" | \"en\", now = Date.now()): string {\n const ms = typeof ts === \"number\" ? ts : Date.parse(ts);\n if (!Number.isFinite(ms)) return \"\";\n const m = Math.floor((now - ms) / 60_000);\n if (m < 1) return lang === \"da\" ? \"nu\" : \"now\";\n if (m < 60) return `${m} min`;\n const h = Math.floor(m / 60);\n if (h < 24) return lang === \"da\" ? `${h} t` : `${h} h`;\n const d = Math.floor(h / 24);\n if (d === 1) return lang === \"da\" ? \"i går\" : \"yesterday\";\n return `${d} d`;\n}\n\n// ── Text ───────────────────────────────────────────────────────────────────\n\nexport const TEXT = {\n da: {\n openMenu: \"Åbn menu\",\n closeMenu: \"Luk menu\",\n home: \"Forside\",\n collapse: \"Skjul sidemenu\",\n expand: \"Vis sidemenu\",\n notifications: \"Notifikationer\",\n markAllRead: \"Markér alle læst\",\n noNotifications: \"Ingen notifikationer endnu.\",\n couldNotLoad: \"Kunne ikke hente notifikationer.\",\n seeAll: \"Vis alle\",\n close: \"Luk\",\n account: \"Konto\",\n signOut: \"Log ud\",\n theme: \"Tema\",\n light: \"Lys\",\n dark: \"Mørk\",\n system: \"System\",\n palette: \"Palet\",\n surfaces: \"Flader\",\n flat: \"Flade\",\n layered: \"Lag\",\n backdrop: \"Baggrund\",\n neurons: \"Neuroner\",\n plain: \"Ren\",\n },\n en: {\n openMenu: \"Open menu\",\n closeMenu: \"Close menu\",\n home: \"Home\",\n collapse: \"Hide sidebar\",\n expand: \"Show sidebar\",\n notifications: \"Notifications\",\n markAllRead: \"Mark all read\",\n noNotifications: \"No notifications yet.\",\n couldNotLoad: \"Could not load notifications.\",\n seeAll: \"See all\",\n close: \"Close\",\n account: \"Account\",\n signOut: \"Sign out\",\n theme: \"Theme\",\n light: \"Light\",\n dark: \"Dark\",\n system: \"System\",\n palette: \"Palette\",\n surfaces: \"Surfaces\",\n flat: \"Flat\",\n layered: \"Layered\",\n backdrop: \"Backdrop\",\n neurons: \"Neurons\",\n plain: \"Plain\",\n },\n} as const;\nexport type Lang = keyof typeof TEXT;\n","/** @jsxImportSource preact */\n// @broberg/app-shell/preact — the fleet's app shell for Stack B (F092).\n//\n// Lifted in shape from cardmem (apps/web/src/components/ui: top-nav, app-sidebar,\n// notification-bell, user-menu, page-header, page-tabs; origin/main af80f192)\n// and trail (the original), rewritten as props-in components: nothing here\n// knows about any app's auth, router or data. Styling is css/app-shell.css,\n// on @broberg/theme's tokens, so every palette × light/dark × flat/layered works.\n//\n// Use the whole thing:\n// <AppShell brand={…} groups={…} currentPath={path} user={…} notifications={source}\n// accountHref=\"https://id.broberg.ai/account\" onSignOut={…}>{page}</AppShell>\n// or compose the parts (Sidebar, TopBar, NotificationBell, UserMenu,\n// PageHeader, PageTabs) in your own layout.\n\nimport type { ComponentChildren, JSX } from \"preact\";\nimport { useEffect, useMemo, useRef, useState } from \"preact/hooks\";\nimport { createBellShell } from \"@broberg/notifications/shell\";\nimport {\n getBackdrop,\n getPalette,\n getPreference,\n getSurfaces,\n onBackdropChange,\n onPaletteChange,\n onSurfacesChange,\n onThemeChange,\n PALETTE_LABELS,\n PALETTES,\n setBackdrop,\n setPalette,\n setPreference,\n setSurfaces,\n type Backdrop,\n type Palette,\n type Surfaces,\n type ThemePreference,\n} from \"@broberg/theme\";\nimport {\n activeNavLabel,\n badgeLabel,\n initials,\n isActivePath,\n readFlag,\n readSet,\n relativeTime,\n safeNavigate,\n TEXT,\n writeFlag,\n writeSet,\n type Lang,\n type NavGroup,\n type NavItem,\n type NotificationRow,\n type NotificationSource,\n} from \"./index\";\n\nexport * from \"./index\";\n\ntype Icon = ComponentChildren;\nexport type PreactNavItem = NavItem<Icon>;\nexport type PreactNavGroup = NavGroup<Icon>;\n/** Called instead of a full page load when given. Return false to let the browser navigate. */\nexport type Navigate = (href: string) => void;\n\nconst MOBILE_QUERY = \"(max-width: 767px)\";\n\n/** True below 768px. Follows the window as it resizes. */\nexport function useIsMobile(): boolean {\n const get = () => typeof window !== \"undefined\" && typeof window.matchMedia === \"function\" && window.matchMedia(MOBILE_QUERY).matches;\n const [mobile, setMobile] = useState(get);\n useEffect(() => {\n if (typeof window === \"undefined\" || typeof window.matchMedia !== \"function\") return;\n const mq = window.matchMedia(MOBILE_QUERY);\n const on = () => setMobile(mq.matches);\n mq.addEventListener?.(\"change\", on);\n return () => mq.removeEventListener?.(\"change\", on);\n }, []);\n return mobile;\n}\n\n/** An <a> that hands the click to `onNavigate` (SPA) when given, else a normal link. */\nfunction NavLink(props: {\n href: string;\n onNavigate?: Navigate;\n onAfter?: () => void;\n class?: string;\n children: ComponentChildren;\n \"data-testid\"?: string;\n \"aria-current\"?: \"page\";\n title?: string;\n}) {\n const { href, onNavigate, onAfter, children, ...rest } = props;\n return (\n <a\n {...rest}\n href={href}\n onClick={(e: JSX.TargetedMouseEvent<HTMLAnchorElement>) => {\n if (onNavigate && !e.metaKey && !e.ctrlKey && !e.shiftKey && e.button === 0) {\n e.preventDefault();\n onNavigate(href);\n }\n onAfter?.();\n }}\n >\n {children}\n </a>\n );\n}\n\n// ── Icons (inline, so the package has no icon dependency) ─────────────────\nconst svg = (d: ComponentChildren, size = 18) => (\n <svg viewBox=\"0 0 24 24\" width={size} height={size} fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.9\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\">\n {d}\n </svg>\n);\nconst IconMenu = () => svg(<path d=\"M4 6h16M4 12h16M4 18h16\" />, 20);\nconst IconChevron = ({ open }: { open?: boolean }) => (\n <span class={\"bas-chev\" + (open ? \" is-open\" : \"\")}>{svg(<path d=\"m9 18 6-6-6-6\" />, 12)}</span>\n);\n// lucide \"panel-left\" (ISC), the exact icon in shadcn's SidebarTrigger (F092.4).\nconst IconPanelLeft = () => svg(<><rect width=\"18\" height=\"18\" x=\"3\" y=\"3\" rx=\"2\" /><path d=\"M9 3v18\" /></>, 16);\nconst IconBell = () => svg(<><path d=\"M6 8a6 6 0 0 1 12 0c0 7 3 9 3 9H3s3-2 3-9\" /><path d=\"M10.3 21a1.94 1.94 0 0 0 3.4 0\" /></>, 19);\nconst IconLogOut = () => svg(<><path d=\"M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4\" /><path d=\"m16 17 5-5-5-5\" /><path d=\"M21 12H9\" /></>, 14);\nconst IconUser = () => svg(<><circle cx=\"12\" cy=\"8\" r=\"4\" /><path d=\"M4 21a8 8 0 0 1 16 0\" /></>, 14);\n\n// ── Sidebar ────────────────────────────────────────────────────────────────\n\nexport interface SidebarProps {\n groups: PreactNavGroup[];\n footer?: PreactNavItem[];\n currentPath: string;\n onNavigate?: Navigate;\n /** Desktop: is the sidebar folded (to nothing, or to the icon rail — see `collapse`). */\n collapsed?: boolean;\n /**\n * F092.6 — what \"folded\" means on desktop, as shadcn's `collapsible`:\n * \"offcanvas\" hides the sidebar, \"icon\" keeps a 48px rail of item icons with\n * `brandMark` on top. Default: \"icon\" when `mobile` is \"rail\", else \"offcanvas\".\n */\n collapse?: \"offcanvas\" | \"icon\";\n /** The app's logo icon, shown at the top of the icon rail. */\n brandMark?: ComponentChildren;\n /** F092.7 — the app's start page: `header` and `brandMark` become links to it. */\n homeHref?: string;\n /** Accessible name of the brandMark link (it has no visible text). Default \"Forside\"/\"Home\". */\n homeLabel?: string;\n /** Phone, drawer mode: is the drawer open. */\n mobileOpen?: boolean;\n onClose?: () => void;\n mobile?: \"drawer\" | \"rail\";\n /** Shown at the top of the sidebar (e.g. the brand on a phone). */\n header?: ComponentChildren;\n /** localStorage key for which groups are folded. */\n groupsKey?: string;\n /** localStorage key for which items with children are open (F092.5). */\n itemsKey?: string;\n lang: Lang;\n}\n\nexport function Sidebar(p: SidebarProps) {\n const key = p.groupsKey ?? \"broberg-app-shell.groups\";\n const itemsKey = p.itemsKey ?? \"broberg-app-shell.items\";\n const mode = p.mobile ?? \"drawer\";\n const collapseMode = p.collapse ?? (mode === \"rail\" ? \"icon\" : \"offcanvas\");\n const isMobile = useIsMobile();\n // The rail: on a phone in rail mode, or on desktop when folded to icons.\n const railed = isMobile ? mode === \"rail\" : !!p.collapsed && collapseMode === \"icon\";\n\n const [folded, setFolded] = useState<Set<string>>(() => readSet(key));\n const toggleGroup = (label: string) => {\n const next = new Set(folded);\n next.has(label) ? next.delete(label) : next.add(label);\n setFolded(next);\n writeSet(key, next);\n };\n\n const all = [...p.groups.flatMap((g) => g.items), ...(p.footer ?? [])];\n const childActive = (it: PreactNavItem) => !!it.children?.some((c) => isActivePath(c.href, p.currentPath));\n // Open = what the user left open, plus any parent of the page they are on.\n const [openItems, setOpenItems] = useState<Set<string>>(() => {\n const s = readSet(itemsKey);\n for (const it of all) if (childActive(it)) s.add(it.id);\n return s;\n });\n const toggleItem = (id: string) => {\n const next = new Set(openItems);\n next.has(id) ? next.delete(id) : next.add(id);\n setOpenItems(next);\n writeSet(itemsKey, next);\n };\n\n // F092.6 — the rail's flyout for an item with children.\n const [flyout, setFlyout] = useState<{ id: string; top: number; left: number } | null>(null);\n const flyoutRef = useRef<HTMLDivElement>(null);\n useEffect(() => {\n if (!flyout) return;\n const onKey = (e: KeyboardEvent) => {\n if (e.key === \"Escape\") setFlyout(null);\n };\n const onDown = (e: MouseEvent) => {\n const t = e.target as Node | null;\n if (flyoutRef.current && t && flyoutRef.current.contains(t)) return;\n if (t instanceof Element && t.closest(`[data-flyout-for=\"${flyout.id}\"]`)) return;\n setFlyout(null);\n };\n document.addEventListener(\"keydown\", onKey);\n document.addEventListener(\"mousedown\", onDown);\n return () => {\n document.removeEventListener(\"keydown\", onKey);\n document.removeEventListener(\"mousedown\", onDown);\n };\n }, [flyout]);\n useEffect(() => {\n if (!railed) setFlyout(null);\n }, [railed]);\n\n const close = () => {\n setFlyout(null);\n p.onClose?.();\n };\n\n const leaf = (it: PreactNavItem, sub = false) => {\n const active = isActivePath(it.href, p.currentPath);\n const badge = badgeLabel(it.badge);\n return (\n <NavLink\n key={it.id}\n href={it.href}\n onNavigate={p.onNavigate}\n onAfter={close}\n class={\"bas-item\" + (sub ? \" bas-item--sub\" : \"\") + (active ? \" is-active\" : \"\")}\n data-testid={`sidebar-item-${it.id}`}\n aria-current={active ? \"page\" : undefined}\n aria-label={railed && !sub ? it.label : undefined}\n title={it.label}\n >\n {active && !sub ? <span class=\"bas-item__bar\" /> : null}\n {it.icon ? <span class=\"bas-item__icon\">{it.icon}</span> : null}\n <span class=\"bas-item__label\">{it.label}</span>\n {badge ? <span class=\"bas-item__count\" data-testid={`sidebar-badge-${it.id}`}>{badge}</span> : null}\n </NavLink>\n );\n };\n\n const parent = (it: PreactNavItem) => {\n const children = it.children!;\n const onPage = childActive(it) || isActivePath(it.href, p.currentPath);\n const open = railed ? flyout?.id === it.id : openItems.has(it.id);\n const onClick = (e: JSX.TargetedMouseEvent<HTMLButtonElement>) => {\n if (!railed) return toggleItem(it.id);\n if (flyout?.id === it.id) return setFlyout(null);\n const r = e.currentTarget.getBoundingClientRect();\n setFlyout({ id: it.id, top: r.top, left: r.right + 6 });\n };\n return (\n <div class=\"bas-itemgroup\" key={it.id}>\n <button\n type=\"button\"\n class={\"bas-item bas-item--parent\" + (onPage ? \" is-parent-active\" : \"\")}\n data-testid={`sidebar-item-${it.id}-toggle`}\n data-flyout-for={it.id}\n aria-expanded={open}\n aria-label={railed ? it.label : undefined}\n title={it.label}\n onClick={onClick}\n >\n {onPage && railed ? <span class=\"bas-item__bar\" /> : null}\n {it.icon ? <span class=\"bas-item__icon\">{it.icon}</span> : null}\n <span class=\"bas-item__label\">{it.label}</span>\n <span class=\"bas-item__chev\">\n <IconChevron open={open} />\n </span>\n </button>\n {!railed && open ? <div class=\"bas-sub\">{children.map((c) => leaf(c, true))}</div> : null}\n {railed && flyout?.id === it.id ? (\n <div\n ref={flyoutRef}\n class=\"bas-flyout\"\n data-testid={`sidebar-flyout-${it.id}`}\n role=\"menu\"\n aria-label={it.label}\n style={{ top: `${flyout.top}px`, left: `${flyout.left}px` }}\n >\n <div class=\"bas-flyout__title\">{it.label}</div>\n {children.map((c) => leaf(c, true))}\n </div>\n ) : null}\n </div>\n );\n };\n\n const item = (it: PreactNavItem) => (it.children?.length ? parent(it) : leaf(it));\n\n return (\n <>\n {mode === \"drawer\" ? (\n <div class={\"bas-backdrop\" + (p.mobileOpen ? \" is-open\" : \"\")} data-testid=\"sidebar-backdrop\" onClick={close} />\n ) : null}\n <aside\n class={\n \"bas-sidebar\" +\n ` is-mobile-${mode}` +\n (p.mobileOpen ? \" is-open\" : \"\") +\n (p.collapsed ? \" is-collapsed\" : \"\") +\n (railed ? \" is-railed\" : \"\")\n }\n data-testid=\"sidebar-root\"\n data-mobile={mode}\n data-collapse={collapseMode}\n aria-label=\"Navigation\"\n >\n {p.header || p.brandMark ? (\n <div class=\"bas-sidebar__head\">\n {p.header ? (\n <div class=\"bas-sidebar__brand\">\n {p.homeHref ? (\n <NavLink href={p.homeHref} onNavigate={p.onNavigate} onAfter={close} class=\"bas-home\" data-testid=\"sidebar-brand-home\">\n {p.header}\n </NavLink>\n ) : (\n p.header\n )}\n </div>\n ) : null}\n {p.brandMark ? (\n <div class=\"bas-sidebar__mark\" data-testid=\"sidebar-brand-mark\">\n {p.homeHref ? (\n <NavLink\n href={p.homeHref}\n onNavigate={p.onNavigate}\n onAfter={close}\n class=\"bas-home\"\n data-testid=\"brand-mark-home\"\n aria-label={p.homeLabel ?? TEXT[p.lang].home}\n title={p.homeLabel ?? TEXT[p.lang].home}\n >\n {p.brandMark}\n </NavLink>\n ) : (\n p.brandMark\n )}\n </div>\n ) : null}\n </div>\n ) : null}\n <nav class=\"bas-sidebar__nav\">\n {p.groups.map((g) => {\n const open = railed || !folded.has(g.label);\n const slug = g.label.toLowerCase().replace(/[^a-z0-9]+/g, \"-\");\n return (\n <div class=\"bas-group\" key={g.label}>\n <button type=\"button\" class=\"bas-group__label\" data-testid={`sidebar-group-${slug}`} aria-expanded={open} onClick={() => toggleGroup(g.label)}>\n <IconChevron open={open} />\n <span>{g.label}</span>\n </button>\n {open ? g.items.map(item) : null}\n </div>\n );\n })}\n </nav>\n {p.footer?.length ? <div class=\"bas-sidebar__foot\">{p.footer.map(item)}</div> : null}\n </aside>\n </>\n );\n}\n\n// ── Notification bell ──────────────────────────────────────────────────────\n//\n// Driven by @broberg/notifications' createBellShell: one count however many\n// bells, Escape acts on the innermost layer, and the ids \"mark all read\"\n// actually cleared are held for the visit. This component is only the DOM.\n\nexport interface NotificationBellProps {\n /** Where the data comes from. Absent: the bell is still there, with an empty list. */\n source?: NotificationSource;\n onNavigate?: Navigate;\n /** Required on purpose: a default would make \"nobody chose\" look like a choice. */\n lang: Lang;\n}\n\nexport function NotificationBell({ source, onNavigate, lang }: NotificationBellProps) {\n const t = TEXT[lang];\n const mobile = useIsMobile();\n const [error, setError] = useState<string | null>(null);\n const lastCount = useRef(0);\n const shell = useMemo(\n () =>\n createBellShell({\n labels: { bell: t.notifications, panel: t.notifications, markAll: t.markAllRead, seeAll: t.seeAll, empty: t.noNotifications, close: t.close },\n countUnseen: async () => {\n if (!source) return 0;\n try {\n lastCount.current = await source.countUnseen();\n setError(null);\n } catch (e) {\n setError(e instanceof Error ? e.message : String(e));\n }\n return lastCount.current;\n },\n loadRows: async () => {\n if (!source) return [];\n try {\n return await source.loadRows();\n } catch (e) {\n setError(e instanceof Error ? e.message : String(e));\n return [];\n }\n },\n markAllSeen: async () => (source ? source.markAllSeen() : []),\n }),\n [source, lang],\n );\n const [state, setState] = useState(shell.getState());\n useEffect(() => shell.subscribe(setState), [shell]);\n useEffect(() => {\n setState(shell.getState());\n void shell.refresh();\n return source?.subscribe?.(() => {\n if (shell.getState().open) void shell.open(shell.getState().anchor);\n else void shell.refresh();\n });\n }, [shell, source]);\n useEffect(() => {\n if (!state.open) return;\n const onKey = (e: KeyboardEvent) => {\n if (e.key === \"Escape\" && shell.escape() === \"close\") e.preventDefault();\n };\n document.addEventListener(\"keydown\", onKey);\n return () => document.removeEventListener(\"keydown\", onKey);\n }, [state.open, shell]);\n\n const label = badgeLabel(state.count);\n const onRow = async (n: NotificationRow) => {\n shell.close();\n if (n.seenAt == null && source) {\n await source.markSeen([n.id]);\n await shell.refresh();\n }\n const target = safeNavigate(n.navigate);\n if (target) {\n if (onNavigate) onNavigate(target);\n else if (typeof window !== \"undefined\") window.location.assign(target);\n }\n };\n const seen = (n: NotificationRow) => n.seenAt != null || state.clearedIds.includes(n.id);\n\n return (\n <div class=\"bas-bell\">\n <button\n type=\"button\"\n class=\"bas-iconbtn\"\n data-testid=\"topbar-notifications\"\n aria-label={t.notifications}\n aria-expanded={state.open}\n onClick={(e: JSX.TargetedMouseEvent<HTMLButtonElement>) => {\n const r = e.currentTarget.getBoundingClientRect();\n void shell.toggle({ top: r.top, right: r.right, bottom: r.bottom, left: r.left, width: r.width, height: r.height } as never);\n }}\n >\n <IconBell />\n {label ? (\n <span class=\"bas-bell__count\" data-testid=\"topbar-notifications-count\">\n {label}\n </span>\n ) : null}\n </button>\n {state.open ? (\n <>\n <div class={\"bas-overlay\" + (mobile ? \" is-dim\" : \"\")} data-testid=\"notifications-backdrop\" onClick={() => shell.close()} />\n <div\n class={\"bas-panel \" + (mobile ? \"bas-panel--sheet\" : \"bas-panel--drop\")}\n role=\"dialog\"\n aria-label={shell.labels.panel}\n data-testid={mobile ? \"notifications-drawer\" : \"notifications-dropdown\"}\n >\n <div class=\"bas-panel__head\">\n <h3>{t.notifications}</h3>\n <button type=\"button\" class=\"bas-link\" data-testid=\"notifications-mark-all\" onClick={() => void shell.markAllSeen()} disabled={!state.count}>\n {shell.labels.markAll}\n </button>\n </div>\n <div class=\"bas-panel__list\" data-testid=\"notifications-list\">\n {error && state.rows.length === 0 ? (\n <p class=\"bas-panel__note is-error\" data-testid=\"notifications-error\">\n {t.couldNotLoad}\n </p>\n ) : state.rows.length === 0 ? (\n <p class=\"bas-panel__note\" data-testid=\"notifications-empty\">\n {shell.labels.empty}\n </p>\n ) : (\n state.rows.map((n) => (\n <button\n type=\"button\"\n key={n.id}\n class={\"bas-note\" + (seen(n) ? \" is-read\" : \"\")}\n data-testid=\"notification-row\"\n data-id={n.id}\n onClick={() => void onRow(n)}\n >\n <span class=\"bas-note__text\">\n <span class=\"bas-note__title\">{n.title}</span>\n {n.body ? <span class=\"bas-note__body\">{n.body}</span> : null}\n <span class=\"bas-note__time\">{relativeTime(n.createdAt, lang)}</span>\n </span>\n {!seen(n) ? <span class=\"bas-note__dot\" /> : null}\n </button>\n ))\n )}\n </div>\n </div>\n </>\n ) : null}\n </div>\n );\n}\n\n// ── User menu ──────────────────────────────────────────────────────────────\n\nexport interface ShellUser {\n name?: string;\n email?: string;\n /** Broberg ID OIDC `picture`. Without it: initials. Never Gravatar (D-1dc849). */\n picture?: string;\n}\nexport interface UserMenuItem {\n id: string;\n label: string;\n icon?: Icon;\n href?: string;\n onSelect?: () => void;\n}\nexport interface UserMenuProps {\n user: ShellUser;\n /** «Konto» → Broberg ID's account page. */\n accountHref?: string;\n items?: UserMenuItem[];\n onSignOut?: () => void | Promise<void>;\n onNavigate?: Navigate;\n /** Show Theme · Palette · Surfaces · Backdrop. Default true. */\n appearance?: boolean;\n lang: Lang;\n}\n\nexport function Avatar({ user, size = 28 }: { user: ShellUser; size?: number }) {\n const [broken, setBroken] = useState(false);\n const style = `width:${size}px;height:${size}px;font-size:${Math.round(size * 0.4)}px`;\n if (user.picture && !broken) {\n return <img class=\"bas-avatar\" style={style} src={user.picture} alt=\"\" referrerpolicy=\"no-referrer\" onError={() => setBroken(true)} data-testid=\"avatar-picture\" />;\n }\n return (\n <span class=\"bas-avatar bas-avatar--initials\" style={style} data-testid=\"avatar-initials\" aria-hidden=\"true\">\n {initials(user.name, user.email)}\n </span>\n );\n}\n\nfunction Segmented<T extends string>(props: { testid: string; value: T; options: readonly (readonly [T, string])[]; onChange: (v: T) => void }) {\n return (\n <div class=\"bas-seg\" data-testid={props.testid} role=\"group\">\n {props.options.map(([v, label]) => (\n <button type=\"button\" key={v} aria-pressed={props.value === v} data-testid={`${props.testid}-${v}`} onClick={() => props.onChange(v)}>\n {label}\n </button>\n ))}\n </div>\n );\n}\n\nexport function UserMenu(p: UserMenuProps) {\n const t = TEXT[p.lang];\n const [open, setOpen] = useState(false);\n const [busy, setBusy] = useState(false);\n const root = useRef<HTMLDivElement>(null);\n const [pref, setPref] = useState<ThemePreference>(() => getPreference());\n const [palette, setPal] = useState<Palette>(() => getPalette());\n const [surfaces, setSurf] = useState<Surfaces>(() => getSurfaces());\n const [backdrop, setBack] = useState<Backdrop>(() => getBackdrop());\n\n useEffect(() => {\n const offs = [\n onThemeChange(() => setPref(getPreference())),\n onPaletteChange(setPal),\n onSurfacesChange(setSurf),\n onBackdropChange(setBack),\n ];\n return () => offs.forEach((off) => off());\n }, []);\n\n useEffect(() => {\n if (!open) return;\n const onDown = (e: MouseEvent) => {\n if (root.current && !root.current.contains(e.target as Node)) setOpen(false);\n };\n const onKey = (e: KeyboardEvent) => e.key === \"Escape\" && setOpen(false);\n document.addEventListener(\"mousedown\", onDown);\n document.addEventListener(\"keydown\", onKey);\n return () => {\n document.removeEventListener(\"mousedown\", onDown);\n document.removeEventListener(\"keydown\", onKey);\n };\n }, [open]);\n\n const firstName = (p.user.name ?? \"\").trim().split(/\\s+/)[0] || p.user.email || \"\";\n const signOut = async () => {\n setBusy(true);\n try {\n await p.onSignOut?.();\n } finally {\n setBusy(false);\n setOpen(false);\n }\n };\n\n return (\n <div class=\"bas-usermenu\" ref={root}>\n <button\n type=\"button\"\n class={\"bas-userbtn\" + (open ? \" is-open\" : \"\")}\n data-testid=\"topbar-user-menu\"\n aria-haspopup=\"menu\"\n aria-expanded={open}\n aria-label={p.user.email ?? p.user.name ?? t.account}\n onClick={() => setOpen((v) => !v)}\n >\n <Avatar user={p.user} />\n <span class=\"bas-userbtn__name\">{firstName}</span>\n </button>\n {open ? (\n <div class=\"bas-menu\" role=\"menu\" data-testid=\"topbar-user-menu-dropdown\">\n <div class=\"bas-menu__who\">\n <Avatar user={p.user} size={36} />\n <div class=\"bas-menu__whotext\">\n {p.user.name ? <div class=\"bas-menu__name\">{p.user.name}</div> : null}\n {p.user.email ? <div class=\"bas-menu__email\">{p.user.email}</div> : null}\n </div>\n </div>\n <div class=\"bas-sep\" />\n {p.accountHref ? (\n <a class=\"bas-mi\" href={p.accountHref} data-testid=\"user-menu-account\" role=\"menuitem\">\n <IconUser />\n <span>{t.account}</span>\n </a>\n ) : null}\n {(p.items ?? []).map((it) =>\n it.href ? (\n <NavLink key={it.id} href={it.href} onNavigate={p.onNavigate} onAfter={() => setOpen(false)} class=\"bas-mi\" data-testid={`user-menu-${it.id}`}>\n {it.icon ?? null}\n <span>{it.label}</span>\n </NavLink>\n ) : (\n <button\n key={it.id}\n type=\"button\"\n class=\"bas-mi\"\n role=\"menuitem\"\n data-testid={`user-menu-${it.id}`}\n onClick={() => {\n setOpen(false);\n it.onSelect?.();\n }}\n >\n {it.icon ?? null}\n <span>{it.label}</span>\n </button>\n ),\n )}\n {p.appearance !== false ? (\n <>\n <div class=\"bas-sep\" />\n <div class=\"bas-prefs\">\n <div class=\"bas-pref\">\n <span>{t.theme}</span>\n <Segmented\n testid=\"user-menu-theme\"\n value={pref as \"light\" | \"dark\" | \"system\"}\n options={[[\"light\", t.light], [\"dark\", t.dark], [\"system\", t.system]] as const}\n onChange={(v) => {\n setPreference(v);\n setPref(v);\n }}\n />\n </div>\n <div class=\"bas-pref\">\n <span>{t.palette}</span>\n <Segmented testid=\"user-menu-palette\" value={palette} options={PALETTES.map((x) => [x, PALETTE_LABELS[x]] as const)} onChange={setPalette} />\n </div>\n <div class=\"bas-pref\">\n <span>{t.surfaces}</span>\n <Segmented testid=\"user-menu-surfaces\" value={surfaces} options={[[\"flat\", t.flat], [\"layered\", t.layered]] as const} onChange={setSurfaces} />\n </div>\n <div class=\"bas-pref\">\n <span>{t.backdrop}</span>\n <Segmented testid=\"user-menu-backdrop\" value={backdrop} options={[[\"neurons\", t.neurons], [\"plain\", t.plain]] as const} onChange={setBackdrop} />\n </div>\n </div>\n </>\n ) : null}\n {p.onSignOut ? (\n <>\n <div class=\"bas-sep\" />\n <button type=\"button\" class=\"bas-mi is-danger\" role=\"menuitem\" data-testid=\"topbar-sign-out\" disabled={busy} onClick={() => void signOut()}>\n <IconLogOut />\n <span>{t.signOut}</span>\n </button>\n </>\n ) : null}\n </div>\n ) : null}\n </div>\n );\n}\n\n// ── Top bar ────────────────────────────────────────────────────────────────\n\nexport interface TopBarProps {\n /** F092.7 — when set, the brand is a link to the app's start page. */\n homeHref?: string;\n /** Called after the brand link was followed (AppShell closes the drawer). */\n onHome?: () => void;\n brand?: ComponentChildren;\n /** Anything app-specific (project switcher, search) between brand and bell. */\n actions?: ComponentChildren;\n /** Drawer mode on a phone: show the hamburger and call this. */\n onOpenMenu?: () => void;\n notifications?: NotificationSource;\n user?: ShellUser;\n userMenu?: Omit<UserMenuProps, \"user\" | \"lang\" | \"onNavigate\">;\n onNavigate?: Navigate;\n lang: Lang;\n}\n\n/** Brand left, actions, then the notification bell and the user menu ALWAYS last, in that order. */\nexport function TopBar(p: TopBarProps) {\n const t = TEXT[p.lang];\n return (\n <header class=\"bas-topbar\" data-testid=\"topbar-root\">\n <div class=\"bas-topbar__inner\">\n {p.onOpenMenu ? (\n <button type=\"button\" class=\"bas-iconbtn bas-hamburger\" data-testid=\"sidebar-toggle\" aria-label={t.openMenu} onClick={p.onOpenMenu}>\n <IconMenu />\n </button>\n ) : null}\n {p.brand ? (\n <div class=\"bas-topbar__brand\">\n {p.homeHref ? (\n <NavLink href={p.homeHref} onNavigate={p.onNavigate} onAfter={p.onHome} class=\"bas-home\" data-testid=\"brand-home\">\n {p.brand}\n </NavLink>\n ) : (\n p.brand\n )}\n </div>\n ) : null}\n {p.actions ? <div class=\"bas-topbar__actions\">{p.actions}</div> : null}\n <div class=\"bas-spacer\" />\n <NotificationBell source={p.notifications} onNavigate={p.onNavigate} lang={p.lang} />\n {p.user ? <UserMenu user={p.user} {...p.userMenu} onNavigate={p.onNavigate} lang={p.lang} /> : null}\n </div>\n </header>\n );\n}\n\n// ── Page header + tabs ─────────────────────────────────────────────────────\n\nexport function PageHeader(p: { eyebrow?: ComponentChildren; title: ComponentChildren; description?: ComponentChildren; actions?: ComponentChildren }) {\n return (\n <div class=\"bas-pagehead\" data-testid=\"page-header\">\n <div class=\"bas-pagehead__text\">\n {p.eyebrow ? <div class=\"bas-pagehead__eyebrow\">{p.eyebrow}</div> : null}\n <h1 class=\"bas-pagehead__title\">{p.title}</h1>\n {p.description ? <p class=\"bas-pagehead__desc\">{p.description}</p> : null}\n </div>\n {p.actions ? <div class=\"bas-pagehead__actions\">{p.actions}</div> : null}\n </div>\n );\n}\n\nexport interface PageTab {\n id: string;\n label: ComponentChildren;\n /** Path mode: the tab's own route. Query mode: ignored (?tab=id is used). */\n href?: string;\n}\n\n/**\n * Tabs as routes. `mode: \"query\"` puts the tab in `?tab=<id>` on the current\n * path (first tab when absent); `mode: \"path\"` gives each tab its own href.\n */\nexport function PageTabs(p: { tabs: PageTab[]; currentUrl: string; mode?: \"query\" | \"path\"; onNavigate?: Navigate }) {\n const mode = p.mode ?? \"query\";\n const url = new URL(p.currentUrl, \"http://x\");\n const activeId =\n mode === \"query\"\n ? url.searchParams.get(\"tab\") ?? p.tabs[0]?.id\n : p.tabs.find((tab) => tab.href && isActivePath(tab.href, url.pathname))?.id;\n return (\n <div class=\"bas-tabs\" role=\"tablist\" data-testid=\"page-tabs\">\n {p.tabs.map((tab) => {\n let href = tab.href ?? \"\";\n if (mode === \"query\") {\n const u = new URL(url.toString());\n u.searchParams.set(\"tab\", tab.id);\n href = u.pathname + u.search;\n }\n const active = tab.id === activeId;\n return (\n <NavLink key={tab.id} href={href} onNavigate={p.onNavigate} class={\"bas-tab\" + (active ? \" is-active\" : \"\")} data-testid={`page-tab-${tab.id}`} aria-current={active ? \"page\" : undefined}>\n {tab.label}\n </NavLink>\n );\n })}\n </div>\n );\n}\n\n// ── App shell ──────────────────────────────────────────────────────────────\n\nexport interface AppShellProps {\n brand?: ComponentChildren;\n actions?: ComponentChildren;\n groups: PreactNavGroup[];\n footer?: PreactNavItem[];\n currentPath: string;\n onNavigate?: Navigate;\n /** The notification centre's source. The bell is shown either way. */\n notifications?: NotificationSource;\n user?: ShellUser;\n userMenu?: Omit<UserMenuProps, \"user\" | \"lang\" | \"onNavigate\">;\n /** Phone behaviour: a slide-in drawer, or a 60px icon rail. */\n mobile?: \"drawer\" | \"rail\";\n /**\n * F092.6 — desktop fold: \"offcanvas\" hides the sidebar, \"icon\" keeps a 48px\n * icon rail with `brandMark` on top. Default: \"icon\" when `mobile` is \"rail\".\n */\n collapse?: \"offcanvas\" | \"icon\";\n /** The app's logo icon for the top of the icon rail. */\n brandMark?: ComponentChildren;\n /** F092.7 — the app's start page. Brand and brandMark become links to it; on a phone the click closes the drawer. */\n homeHref?: string;\n /** Accessible name for the brandMark link. Default \"Forside\"/\"Home\". */\n homeLabel?: string;\n /**\n * F092.4 — the page title in the content header, after the sidebar button.\n * Absent: the label of the active nav item (a sub-item wins over its parent).\n */\n title?: ComponentChildren;\n /** localStorage key prefix for the folded sidebar, folded groups and open items. */\n storageKey?: string;\n /** Required: the shell ships no default language (see @broberg/notifications/shell). */\n lang: Lang;\n children?: ComponentChildren;\n}\n\nexport function AppShell(p: AppShellProps) {\n const prefix = p.storageKey ?? \"broberg-app-shell\";\n const mode = p.mobile ?? \"drawer\";\n const collapse = p.collapse ?? (mode === \"rail\" ? \"icon\" : \"offcanvas\");\n const [collapsed, setCollapsed] = useState(() => readFlag(`${prefix}.collapsed`, false));\n const [drawer, setDrawer] = useState(false);\n const isMobile = useIsMobile();\n const t = TEXT[p.lang];\n const toggle = () => {\n const next = !collapsed;\n setCollapsed(next);\n writeFlag(`${prefix}.collapsed`, next);\n };\n // F092.4 — ONE sidebar button: the drawer on a phone, the fold on desktop.\n const drawerMode = isMobile && mode === \"drawer\";\n const onTrigger = () => (drawerMode ? setDrawer(!drawer) : toggle());\n const expanded = drawerMode ? drawer : !collapsed;\n const triggerLabel = drawerMode ? (drawer ? t.closeMenu : t.openMenu) : collapsed ? t.expand : t.collapse;\n const heading = p.title ?? activeNavLabel(p.groups, p.footer, p.currentPath);\n return (\n <div class=\"bas-root\" data-testid=\"app-shell\" data-mobile={mode}>\n <TopBar\n brand={p.brand}\n homeHref={p.homeHref}\n onHome={() => setDrawer(false)}\n actions={p.actions}\n notifications={p.notifications}\n user={p.user}\n userMenu={p.userMenu}\n onNavigate={p.onNavigate}\n lang={p.lang}\n />\n <div class=\"bas-row\">\n <Sidebar\n groups={p.groups}\n footer={p.footer}\n currentPath={p.currentPath}\n onNavigate={p.onNavigate}\n collapsed={collapsed}\n collapse={collapse}\n brandMark={p.brandMark}\n homeHref={p.homeHref}\n homeLabel={p.homeLabel}\n mobileOpen={drawer}\n onClose={() => setDrawer(false)}\n mobile={mode}\n header={mode === \"drawer\" ? p.brand : undefined}\n groupsKey={`${prefix}.groups`}\n itemsKey={`${prefix}.items`}\n lang={p.lang}\n />\n <main class=\"bas-main\" data-testid=\"app-content\">\n <div class=\"bas-contenthead\" data-testid=\"content-header\">\n <button\n type=\"button\"\n class=\"bas-iconbtn bas-trigger\"\n data-testid=\"sidebar-trigger\"\n aria-label={triggerLabel}\n aria-expanded={expanded}\n title={triggerLabel}\n onClick={onTrigger}\n >\n <IconPanelLeft />\n </button>\n {heading ? (\n <>\n <span class=\"bas-contenthead__sep\" data-testid=\"content-header-separator\" aria-hidden=\"true\" />\n <h1 class=\"bas-contenthead__title\" data-testid=\"content-header-title\">\n {heading}\n </h1>\n </>\n ) : null}\n </div>\n {p.children}\n </main>\n </div>\n </div>\n );\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/preact.tsx"],"names":["useState","useEffect","jsx","jsxs","Fragment","useRef","shell","useMemo","createBellShell","getPreference","getPalette","getSurfaces","getBackdrop","onThemeChange","onPaletteChange","onSurfacesChange","onBackdropChange","setPreference","PALETTES","PALETTE_LABELS","setPalette","setSurfaces","setBackdrop"],"mappings":"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","file":"preact.cjs","sourcesContent":["// @broberg/app-shell — the framework-free core of the fleet's app shell (F092).\n//\n// The shell every app in the fleet had been copying: sidebar + top bar +\n// notification bell + user menu. cardmem and trail each had one (\"ported from\n// trail\"), and helpdesk and the appkit starter would have made the third and\n// fourth. This file holds what does not depend on a framework: the navigation\n// data model, the notification contract and its sources, and the small rules\n// both the Preact and React parts must agree on.\n//\n// Christian, 4 Oct 2026: notifications are a STANDARD part of the template, not\n// an optional slot — so the contract and a default source live here, and a new\n// app gets a working notification centre by pointing one URL at its backend.\n\n// ── Navigation ─────────────────────────────────────────────────────────────\n\n/** One sidebar entry. `icon` is whatever your framework renders (an element). */\nexport interface NavItem<Icon = unknown> {\n id: string;\n label: string;\n href: string;\n icon?: Icon;\n /** A count shown on the item (99+ above 99). 0/undefined shows nothing. */\n badge?: number;\n /**\n * Sub-items, ONE level (F092.5). An item with children is a toggle that opens\n * and closes them, not a link; its own `href` is used only to decide whether\n * it is on the current path.\n */\n children?: NavItem<Icon>[];\n}\nexport interface NavGroup<Icon = unknown> {\n label: string;\n items: NavItem<Icon>[];\n}\n\n/**\n * Is this item the current page? Exact match for \"/\", otherwise the path is the\n * item or below it (\"/board/123\" is on \"/board\", \"/boardroom\" is not).\n */\nexport function isActivePath(href: string, currentPath: string): boolean {\n const path = (currentPath.split(/[?#]/)[0] || \"/\").replace(/\\/+$/, \"\") || \"/\";\n const target = (href.split(/[?#]/)[0] || \"/\").replace(/\\/+$/, \"\") || \"/\";\n if (target === \"/\") return path === \"/\";\n return path === target || path.startsWith(target + \"/\");\n}\n\n/**\n * A notification's `navigate` is SERVER DATA, and it ends in `location.assign`.\n * `javascript:` there runs code in the app, so only a same-site path or an\n * http(s) URL is followed; anything else returns null and the row just closes.\n */\nexport function safeNavigate(target: string | null | undefined): string | null {\n if (typeof target !== \"string\") return null;\n const t = target.trim();\n if (t.startsWith(\"/\") && !t.startsWith(\"//\") && !t.startsWith(\"/\\\\\")) return t;\n try {\n const u = new URL(t);\n return u.protocol === \"https:\" || u.protocol === \"http:\" ? u.href : null;\n } catch {\n return null;\n }\n}\n\n/**\n * The label of the nav item the user is on, for the content header (F092.4).\n * Sub-items count, and the most specific match wins: on \"/models/genesis\" a\n * \"Genesis\" child beats its \"Models\" parent.\n */\nexport function activeNavLabel<Icon>(\n groups: NavGroup<Icon>[],\n footer: NavItem<Icon>[] | undefined,\n currentPath: string,\n): string | undefined {\n let best: { label: string; len: number } | undefined;\n const visit = (it: NavItem<Icon>) => {\n if (it.href && isActivePath(it.href, currentPath)) {\n const len = it.href.length;\n if (!best || len > best.len) best = { label: it.label, len };\n }\n it.children?.forEach(visit);\n };\n for (const g of groups) g.items.forEach(visit);\n footer?.forEach(visit);\n return best?.label;\n}\n\n/** \"99+\" above 99, nothing for 0 or less. */\nexport function badgeLabel(n: number | undefined): string | null {\n if (!n || n <= 0) return null;\n return n > 99 ? \"99+\" : String(n);\n}\n\n// ── Persisted UI state ─────────────────────────────────────────────────────\n\n/** Read a boolean flag from localStorage; storage errors read as `fallback`. */\nexport function readFlag(key: string, fallback: boolean): boolean {\n try {\n const v = typeof localStorage === \"undefined\" ? null : localStorage.getItem(key);\n return v === null ? fallback : v === \"1\";\n } catch {\n return fallback;\n }\n}\nexport function writeFlag(key: string, value: boolean): void {\n try {\n if (typeof localStorage !== \"undefined\") localStorage.setItem(key, value ? \"1\" : \"0\");\n } catch {\n /* private mode / quota: the UI still works, it just does not remember */\n }\n}\nexport function readSet(key: string): Set<string> {\n try {\n const raw = typeof localStorage === \"undefined\" ? null : localStorage.getItem(key);\n const v = raw ? (JSON.parse(raw) as unknown) : [];\n return new Set(Array.isArray(v) ? v.filter((x): x is string => typeof x === \"string\") : []);\n } catch {\n return new Set();\n }\n}\nexport function writeSet(key: string, value: Set<string>): void {\n try {\n if (typeof localStorage !== \"undefined\") localStorage.setItem(key, JSON.stringify([...value]));\n } catch {\n /* see writeFlag */\n }\n}\n\n// ── Avatar ─────────────────────────────────────────────────────────────────\n\n/**\n * Two initials for the avatar fallback: first letter of the first and the last\n * word, upper-cased. One word gives one letter; nothing gives \"?\".\n *\n * There is deliberately no Gravatar here (owner decision D-1dc849): the avatar\n * is the Broberg ID `picture`, and without one, initials. Gravatar would send a\n * hash of the user's email to a US service on every render.\n */\nexport function initials(name: string | undefined, email?: string): string {\n const source = (name ?? \"\").trim() || (email ?? \"\").split(\"@\")[0] || \"\";\n const words = source.split(/[\\s._-]+/).filter(Boolean);\n if (words.length === 0) return \"?\";\n const first = words[0]![0] ?? \"\";\n const last = words.length > 1 ? words[words.length - 1]![0] ?? \"\" : \"\";\n return (first + last).toUpperCase() || \"?\";\n}\n\n// ── Notifications ──────────────────────────────────────────────────────────\n//\n// REUSE, NOT A SECOND CONTRACT. The fleet already agreed the notification shape\n// in @broberg/notifications (F074): `NotificationRow` — the same field names\n// @broberg/webpush sends, end to end — and the server core that owns the ONE\n// counting rule. The shell's bell renders that row and drives its panel with\n// that package's `createBellShell`, so a server built on `createNotifications`\n// and this bell speak the same language without an adapter.\n//\n// Christian, 4 Oct 2026: notifications are a STANDARD part of the template. So\n// a source, and a default one, ship here: point one URL at your backend.\n\nimport type { NotificationRow } from \"@broberg/notifications/types\";\nexport type { NotificationRow } from \"@broberg/notifications/types\";\n\n/** Where the bell gets its data. Swap it to point at any backend. */\nexport interface NotificationSource {\n /** The rows to show (newest first). */\n loadRows(): Promise<NotificationRow[]>;\n /** THE count — your server's, which may exclude muted kinds (F074's counting rule). */\n countUnseen(): Promise<number>;\n /** Returns the ids that actually transitioned to seen. */\n markSeen(ids: readonly string[]): Promise<string[]>;\n markAllSeen(): Promise<string[]>;\n /** Called with a callback that re-counts; return an unsubscribe. Optional. */\n subscribe?(onChange: () => void): () => void;\n}\n\n/**\n * The default source: a URL on your own backend, shaped after\n * @broberg/notifications' server core so `createNotifications` sits right\n * behind it.\n *\n * GET {url} → { items: NotificationRow[], unseen: number }\n * POST {url}/seen { ids: string[] } → { clearedIds: string[], count: number }\n * POST {url}/seen-all → { clearedIds: string[], count: number }\n *\n * It re-counts when the window regains focus or the tab becomes visible, and on\n * a timer (default 60 s). A failed GET THROWS — the bell shows «could not\n * load», never an empty list: \"could not fetch\" and \"nothing new\" must not look\n * the same.\n */\nexport function createFetchNotificationSource(opts: {\n url: string;\n fetch?: typeof fetch;\n /** Re-count interval in ms. 0 turns it off. Default 60 000. */\n pollMs?: number;\n credentials?: RequestCredentials;\n}): NotificationSource {\n const base = opts.url.replace(/\\/+$/, \"\");\n const doFetch = (input: string, init?: RequestInit) =>\n (opts.fetch ?? fetch)(input, { credentials: opts.credentials ?? \"include\", ...init });\n const get = async (): Promise<{ items: NotificationRow[]; unseen: number }> => {\n const res = await doFetch(base, { headers: { accept: \"application/json\" } });\n if (!res.ok) throw new Error(`HTTP ${res.status}`);\n const body = (await res.json().catch(() => null)) as { items?: unknown; unseen?: unknown } | null;\n if (!body || !Array.isArray(body.items)) throw new Error(\"response has no items array\");\n const items = body.items as NotificationRow[];\n const unseen = typeof body.unseen === \"number\" ? body.unseen : items.filter((n) => n.seenAt == null).length;\n return { items, unseen };\n };\n const post = async (path: string, body?: unknown): Promise<string[]> => {\n const res = await doFetch(`${base}${path}`, {\n method: \"POST\",\n headers: body === undefined ? undefined : { \"content-type\": \"application/json\" },\n body: body === undefined ? undefined : JSON.stringify(body),\n });\n if (!res.ok) throw new Error(`HTTP ${res.status}`);\n const r = (await res.json().catch(() => ({}))) as { clearedIds?: unknown };\n return Array.isArray(r.clearedIds) ? (r.clearedIds as string[]) : [];\n };\n return {\n loadRows: async () => (await get()).items,\n countUnseen: async () => (await get()).unseen,\n markSeen: (ids) => post(\"/seen\", { ids }),\n markAllSeen: () => post(\"/seen-all\"),\n subscribe(onChange) {\n if (typeof window === \"undefined\") return () => {};\n const onVisible = () => {\n if (document.visibilityState === \"visible\") onChange();\n };\n window.addEventListener(\"focus\", onChange);\n document.addEventListener(\"visibilitychange\", onVisible);\n const ms = opts.pollMs ?? 60_000;\n const timer = ms > 0 ? setInterval(onChange, ms) : null;\n return () => {\n window.removeEventListener(\"focus\", onChange);\n document.removeEventListener(\"visibilitychange\", onVisible);\n if (timer) clearInterval(timer);\n };\n },\n };\n}\n\n/** An in-memory source for demos and tests. */\nexport function createMemoryNotificationSource(initial: NotificationRow[] = []): NotificationSource & {\n push(n: NotificationRow): void;\n rows(): NotificationRow[];\n} {\n let rows = initial.map((n) => ({ ...n }));\n const listeners = new Set<() => void>();\n const emit = () => listeners.forEach((l) => l());\n const mark = (pred: (n: NotificationRow) => boolean): string[] => {\n const now = Date.now();\n const cleared: string[] = [];\n rows = rows.map((n) => {\n if (n.seenAt == null && pred(n)) {\n cleared.push(n.id);\n return { ...n, seenAt: now };\n }\n return n;\n });\n if (cleared.length) emit();\n return cleared;\n };\n return {\n loadRows: async () => rows.map((n) => ({ ...n })),\n countUnseen: async () => rows.filter((n) => n.seenAt == null).length,\n markSeen: async (ids) => mark((n) => ids.includes(n.id)),\n markAllSeen: async () => mark(() => true),\n subscribe(onChange) {\n listeners.add(onChange);\n return () => listeners.delete(onChange);\n },\n push(n) {\n rows = [n, ...rows];\n emit();\n },\n rows: () => rows.map((n) => ({ ...n })),\n };\n}\n\n/** \"nu\", \"5 min\", \"3 t\", \"i går\", \"4 d\" (da) or the English equivalents. */\nexport function relativeTime(ts: string | number, lang: \"da\" | \"en\", now = Date.now()): string {\n const ms = typeof ts === \"number\" ? ts : Date.parse(ts);\n if (!Number.isFinite(ms)) return \"\";\n const m = Math.floor((now - ms) / 60_000);\n if (m < 1) return lang === \"da\" ? \"nu\" : \"now\";\n if (m < 60) return `${m} min`;\n const h = Math.floor(m / 60);\n if (h < 24) return lang === \"da\" ? `${h} t` : `${h} h`;\n const d = Math.floor(h / 24);\n if (d === 1) return lang === \"da\" ? \"i går\" : \"yesterday\";\n return `${d} d`;\n}\n\n// ── Text ───────────────────────────────────────────────────────────────────\n\nexport const TEXT = {\n da: {\n openMenu: \"Åbn menu\",\n closeMenu: \"Luk menu\",\n home: \"Forside\",\n collapse: \"Skjul sidemenu\",\n expand: \"Vis sidemenu\",\n notifications: \"Notifikationer\",\n markAllRead: \"Markér alle læst\",\n noNotifications: \"Ingen notifikationer endnu.\",\n couldNotLoad: \"Kunne ikke hente notifikationer.\",\n seeAll: \"Vis alle\",\n close: \"Luk\",\n account: \"Konto\",\n signOut: \"Log ud\",\n theme: \"Tema\",\n light: \"Lys\",\n dark: \"Mørk\",\n system: \"System\",\n palette: \"Palet\",\n surfaces: \"Flader\",\n flat: \"Flade\",\n layered: \"Lag\",\n backdrop: \"Baggrund\",\n neurons: \"Neuroner\",\n plain: \"Ren\",\n },\n en: {\n openMenu: \"Open menu\",\n closeMenu: \"Close menu\",\n home: \"Home\",\n collapse: \"Hide sidebar\",\n expand: \"Show sidebar\",\n notifications: \"Notifications\",\n markAllRead: \"Mark all read\",\n noNotifications: \"No notifications yet.\",\n couldNotLoad: \"Could not load notifications.\",\n seeAll: \"See all\",\n close: \"Close\",\n account: \"Account\",\n signOut: \"Sign out\",\n theme: \"Theme\",\n light: \"Light\",\n dark: \"Dark\",\n system: \"System\",\n palette: \"Palette\",\n surfaces: \"Surfaces\",\n flat: \"Flat\",\n layered: \"Layered\",\n backdrop: \"Backdrop\",\n neurons: \"Neurons\",\n plain: \"Plain\",\n },\n} as const;\nexport type Lang = keyof typeof TEXT;\n","/** @jsxImportSource preact */\n// @broberg/app-shell/preact — the fleet's app shell for Stack B (F092).\n//\n// Lifted in shape from cardmem (apps/web/src/components/ui: top-nav, app-sidebar,\n// notification-bell, user-menu, page-header, page-tabs; origin/main af80f192)\n// and trail (the original), rewritten as props-in components: nothing here\n// knows about any app's auth, router or data. Styling is css/app-shell.css,\n// on @broberg/theme's tokens, so every palette × light/dark × flat/layered works.\n//\n// Use the whole thing:\n// <AppShell brand={…} groups={…} currentPath={path} user={…} notifications={source}\n// accountHref=\"https://id.broberg.ai/account\" onSignOut={…}>{page}</AppShell>\n// or compose the parts (Sidebar, TopBar, NotificationBell, UserMenu,\n// PageHeader, PageTabs) in your own layout.\n\nimport type { ComponentChildren, JSX } from \"preact\";\nimport { useEffect, useMemo, useRef, useState } from \"preact/hooks\";\nimport { createBellShell } from \"@broberg/notifications/shell\";\nimport {\n getBackdrop,\n getPalette,\n getPreference,\n getSurfaces,\n onBackdropChange,\n onPaletteChange,\n onSurfacesChange,\n onThemeChange,\n PALETTE_LABELS,\n PALETTES,\n setBackdrop,\n setPalette,\n setPreference,\n setSurfaces,\n type Backdrop,\n type Palette,\n type Surfaces,\n type ThemePreference,\n} from \"@broberg/theme\";\nimport {\n activeNavLabel,\n badgeLabel,\n initials,\n isActivePath,\n readFlag,\n readSet,\n relativeTime,\n safeNavigate,\n TEXT,\n writeFlag,\n writeSet,\n type Lang,\n type NavGroup,\n type NavItem,\n type NotificationRow,\n type NotificationSource,\n} from \"./index\";\n\nexport * from \"./index\";\n\ntype Icon = ComponentChildren;\nexport type PreactNavItem = NavItem<Icon>;\nexport type PreactNavGroup = NavGroup<Icon>;\n/** Called instead of a full page load when given. Return false to let the browser navigate. */\nexport type Navigate = (href: string) => void;\n\nconst MOBILE_QUERY = \"(max-width: 767px)\";\n\n/** True below 768px. Follows the window as it resizes. */\nexport function useIsMobile(): boolean {\n const get = () => typeof window !== \"undefined\" && typeof window.matchMedia === \"function\" && window.matchMedia(MOBILE_QUERY).matches;\n const [mobile, setMobile] = useState(get);\n useEffect(() => {\n if (typeof window === \"undefined\" || typeof window.matchMedia !== \"function\") return;\n const mq = window.matchMedia(MOBILE_QUERY);\n const on = () => setMobile(mq.matches);\n mq.addEventListener?.(\"change\", on);\n return () => mq.removeEventListener?.(\"change\", on);\n }, []);\n return mobile;\n}\n\n/** An <a> that hands the click to `onNavigate` (SPA) when given, else a normal link. */\nfunction NavLink(props: {\n href: string;\n onNavigate?: Navigate;\n onAfter?: () => void;\n class?: string;\n children: ComponentChildren;\n \"data-testid\"?: string;\n \"aria-current\"?: \"page\";\n title?: string;\n}) {\n const { href, onNavigate, onAfter, children, ...rest } = props;\n return (\n <a\n {...rest}\n href={href}\n onClick={(e: JSX.TargetedMouseEvent<HTMLAnchorElement>) => {\n if (onNavigate && !e.metaKey && !e.ctrlKey && !e.shiftKey && e.button === 0) {\n e.preventDefault();\n onNavigate(href);\n }\n onAfter?.();\n }}\n >\n {children}\n </a>\n );\n}\n\n// ── Icons (inline, so the package has no icon dependency) ─────────────────\nconst svg = (d: ComponentChildren, size = 18) => (\n <svg viewBox=\"0 0 24 24\" width={size} height={size} fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.9\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\">\n {d}\n </svg>\n);\nconst IconMenu = () => svg(<path d=\"M4 6h16M4 12h16M4 18h16\" />, 20);\nconst IconChevron = ({ open }: { open?: boolean }) => (\n <span class={\"bas-chev\" + (open ? \" is-open\" : \"\")}>{svg(<path d=\"m9 18 6-6-6-6\" />, 12)}</span>\n);\n// lucide \"panel-left\" (ISC), the exact icon in shadcn's SidebarTrigger (F092.4).\nconst IconPanelLeft = () => svg(<><rect width=\"18\" height=\"18\" x=\"3\" y=\"3\" rx=\"2\" /><path d=\"M9 3v18\" /></>, 16);\nconst IconBell = () => svg(<><path d=\"M6 8a6 6 0 0 1 12 0c0 7 3 9 3 9H3s3-2 3-9\" /><path d=\"M10.3 21a1.94 1.94 0 0 0 3.4 0\" /></>, 19);\nconst IconLogOut = () => svg(<><path d=\"M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4\" /><path d=\"m16 17 5-5-5-5\" /><path d=\"M21 12H9\" /></>, 14);\nconst IconUser = () => svg(<><circle cx=\"12\" cy=\"8\" r=\"4\" /><path d=\"M4 21a8 8 0 0 1 16 0\" /></>, 14);\n\n// ── Sidebar ────────────────────────────────────────────────────────────────\n\nexport interface SidebarProps {\n groups: PreactNavGroup[];\n footer?: PreactNavItem[];\n currentPath: string;\n onNavigate?: Navigate;\n /** Desktop: is the sidebar folded (to nothing, or to the icon rail — see `collapse`). */\n collapsed?: boolean;\n /**\n * F092.6 — what \"folded\" means on desktop, as shadcn's `collapsible`:\n * \"offcanvas\" hides the sidebar, \"icon\" keeps a 48px rail of item icons with\n * `brandMark` on top. Default: \"icon\" when `mobile` is \"rail\", else \"offcanvas\".\n */\n collapse?: \"offcanvas\" | \"icon\";\n /** The app's logo icon, shown at the top of the icon rail. */\n brandMark?: ComponentChildren;\n /** F092.7 — the app's start page: `header` and `brandMark` become links to it. */\n homeHref?: string;\n /** Accessible name of the brandMark link (it has no visible text). Default \"Forside\"/\"Home\". */\n homeLabel?: string;\n /** Phone, drawer mode: is the drawer open. */\n mobileOpen?: boolean;\n onClose?: () => void;\n mobile?: \"drawer\" | \"rail\";\n /** Shown at the top of the sidebar (e.g. the brand on a phone). */\n header?: ComponentChildren;\n /** localStorage key for which groups are folded. */\n groupsKey?: string;\n /** localStorage key for which items with children are open (F092.5). */\n itemsKey?: string;\n lang: Lang;\n}\n\nexport function Sidebar(p: SidebarProps) {\n const key = p.groupsKey ?? \"broberg-app-shell.groups\";\n const itemsKey = p.itemsKey ?? \"broberg-app-shell.items\";\n const mode = p.mobile ?? \"drawer\";\n const collapseMode = p.collapse ?? (mode === \"rail\" ? \"icon\" : \"offcanvas\");\n const isMobile = useIsMobile();\n // The rail: on a phone in rail mode, or on desktop when folded to icons.\n const railed = isMobile ? mode === \"rail\" : !!p.collapsed && collapseMode === \"icon\";\n\n const [folded, setFolded] = useState<Set<string>>(() => readSet(key));\n const toggleGroup = (label: string) => {\n const next = new Set(folded);\n next.has(label) ? next.delete(label) : next.add(label);\n setFolded(next);\n writeSet(key, next);\n };\n\n const all = [...p.groups.flatMap((g) => g.items), ...(p.footer ?? [])];\n const childActive = (it: PreactNavItem) => !!it.children?.some((c) => isActivePath(c.href, p.currentPath));\n // Open = what the user left open, plus any parent of the page they are on.\n const [openItems, setOpenItems] = useState<Set<string>>(() => {\n const s = readSet(itemsKey);\n for (const it of all) if (childActive(it)) s.add(it.id);\n return s;\n });\n const toggleItem = (id: string) => {\n const next = new Set(openItems);\n next.has(id) ? next.delete(id) : next.add(id);\n setOpenItems(next);\n writeSet(itemsKey, next);\n };\n\n // F092.6 — the rail's flyout for an item with children.\n const [flyout, setFlyout] = useState<{ id: string; top: number; left: number } | null>(null);\n const flyoutRef = useRef<HTMLDivElement>(null);\n useEffect(() => {\n if (!flyout) return;\n const onKey = (e: KeyboardEvent) => {\n if (e.key === \"Escape\") setFlyout(null);\n };\n const onDown = (e: MouseEvent) => {\n const t = e.target as Node | null;\n if (flyoutRef.current && t && flyoutRef.current.contains(t)) return;\n if (t instanceof Element && t.closest(`[data-flyout-for=\"${flyout.id}\"]`)) return;\n setFlyout(null);\n };\n document.addEventListener(\"keydown\", onKey);\n document.addEventListener(\"mousedown\", onDown);\n return () => {\n document.removeEventListener(\"keydown\", onKey);\n document.removeEventListener(\"mousedown\", onDown);\n };\n }, [flyout]);\n useEffect(() => {\n if (!railed) setFlyout(null);\n }, [railed]);\n\n const close = () => {\n setFlyout(null);\n p.onClose?.();\n };\n\n const leaf = (it: PreactNavItem, sub = false) => {\n const active = isActivePath(it.href, p.currentPath);\n const badge = badgeLabel(it.badge);\n return (\n <NavLink\n key={it.id}\n href={it.href}\n onNavigate={p.onNavigate}\n onAfter={close}\n class={\"bas-item\" + (sub ? \" bas-item--sub\" : \"\") + (active ? \" is-active\" : \"\")}\n data-testid={`sidebar-item-${it.id}`}\n aria-current={active ? \"page\" : undefined}\n aria-label={railed && !sub ? it.label : undefined}\n title={it.label}\n >\n {active && !sub ? <span class=\"bas-item__bar\" /> : null}\n {it.icon ? <span class=\"bas-item__icon\">{it.icon}</span> : null}\n <span class=\"bas-item__label\">{it.label}</span>\n {badge ? <span class=\"bas-item__count\" data-testid={`sidebar-badge-${it.id}`}>{badge}</span> : null}\n </NavLink>\n );\n };\n\n const parent = (it: PreactNavItem) => {\n const children = it.children!;\n const onPage = childActive(it) || isActivePath(it.href, p.currentPath);\n const open = railed ? flyout?.id === it.id : openItems.has(it.id);\n const onClick = (e: JSX.TargetedMouseEvent<HTMLButtonElement>) => {\n if (!railed) return toggleItem(it.id);\n if (flyout?.id === it.id) return setFlyout(null);\n const r = e.currentTarget.getBoundingClientRect();\n setFlyout({ id: it.id, top: r.top, left: r.right + 6 });\n };\n return (\n <div class=\"bas-itemgroup\" key={it.id}>\n <button\n type=\"button\"\n class={\"bas-item bas-item--parent\" + (onPage ? \" is-parent-active\" : \"\")}\n data-testid={`sidebar-item-${it.id}-toggle`}\n data-flyout-for={it.id}\n aria-expanded={open}\n aria-label={railed ? it.label : undefined}\n title={it.label}\n onClick={onClick}\n >\n {onPage && railed ? <span class=\"bas-item__bar\" /> : null}\n {it.icon ? <span class=\"bas-item__icon\">{it.icon}</span> : null}\n <span class=\"bas-item__label\">{it.label}</span>\n <span class=\"bas-item__chev\">\n <IconChevron open={open} />\n </span>\n </button>\n {!railed && open ? <div class=\"bas-sub\">{children.map((c) => leaf(c, true))}</div> : null}\n {railed && flyout?.id === it.id ? (\n <div\n ref={flyoutRef}\n class=\"bas-flyout\"\n data-testid={`sidebar-flyout-${it.id}`}\n role=\"menu\"\n aria-label={it.label}\n style={{ top: `${flyout.top}px`, left: `${flyout.left}px` }}\n >\n <div class=\"bas-flyout__title\">{it.label}</div>\n {children.map((c) => leaf(c, true))}\n </div>\n ) : null}\n </div>\n );\n };\n\n const item = (it: PreactNavItem) => (it.children?.length ? parent(it) : leaf(it));\n\n return (\n <>\n {mode === \"drawer\" ? (\n <div class={\"bas-backdrop\" + (p.mobileOpen ? \" is-open\" : \"\")} data-testid=\"sidebar-backdrop\" onClick={close} />\n ) : null}\n <aside\n class={\n \"bas-sidebar\" +\n ` is-mobile-${mode}` +\n (p.mobileOpen ? \" is-open\" : \"\") +\n (p.collapsed ? \" is-collapsed\" : \"\") +\n (railed ? \" is-railed\" : \"\")\n }\n data-testid=\"sidebar-root\"\n data-mobile={mode}\n data-collapse={collapseMode}\n aria-label=\"Navigation\"\n >\n {p.header || p.brandMark ? (\n <div class=\"bas-sidebar__head\">\n {p.header ? (\n <div class=\"bas-sidebar__brand\">\n {p.homeHref ? (\n <NavLink href={p.homeHref} onNavigate={p.onNavigate} onAfter={close} class=\"bas-home\" data-testid=\"sidebar-brand-home\">\n {p.header}\n </NavLink>\n ) : (\n p.header\n )}\n </div>\n ) : null}\n {p.brandMark ? (\n <div class=\"bas-sidebar__mark\" data-testid=\"sidebar-brand-mark\">\n {p.homeHref ? (\n <NavLink\n href={p.homeHref}\n onNavigate={p.onNavigate}\n onAfter={close}\n class=\"bas-home\"\n data-testid=\"brand-mark-home\"\n aria-label={p.homeLabel ?? TEXT[p.lang].home}\n title={p.homeLabel ?? TEXT[p.lang].home}\n >\n {p.brandMark}\n </NavLink>\n ) : (\n p.brandMark\n )}\n </div>\n ) : null}\n </div>\n ) : null}\n <nav class=\"bas-sidebar__nav\">\n {p.groups.map((g) => {\n const open = railed || !folded.has(g.label);\n const slug = g.label.toLowerCase().replace(/[^a-z0-9]+/g, \"-\");\n return (\n <div class=\"bas-group\" key={g.label}>\n <button type=\"button\" class=\"bas-group__label\" data-testid={`sidebar-group-${slug}`} aria-expanded={open} onClick={() => toggleGroup(g.label)}>\n <IconChevron open={open} />\n <span>{g.label}</span>\n </button>\n {open ? g.items.map(item) : null}\n </div>\n );\n })}\n </nav>\n {p.footer?.length ? <div class=\"bas-sidebar__foot\">{p.footer.map(item)}</div> : null}\n </aside>\n </>\n );\n}\n\n// ── Notification bell ──────────────────────────────────────────────────────\n//\n// Driven by @broberg/notifications' createBellShell: one count however many\n// bells, Escape acts on the innermost layer, and the ids \"mark all read\"\n// actually cleared are held for the visit. This component is only the DOM.\n\nexport interface NotificationBellProps {\n /** Where the data comes from. Absent: the bell is still there, with an empty list. */\n source?: NotificationSource;\n onNavigate?: Navigate;\n /** Required on purpose: a default would make \"nobody chose\" look like a choice. */\n lang: Lang;\n}\n\nexport function NotificationBell({ source, onNavigate, lang }: NotificationBellProps) {\n const t = TEXT[lang];\n const mobile = useIsMobile();\n const [error, setError] = useState<string | null>(null);\n const lastCount = useRef(0);\n const shell = useMemo(\n () =>\n createBellShell({\n labels: { bell: t.notifications, panel: t.notifications, markAll: t.markAllRead, seeAll: t.seeAll, empty: t.noNotifications, close: t.close },\n countUnseen: async () => {\n if (!source) return 0;\n try {\n lastCount.current = await source.countUnseen();\n setError(null);\n } catch (e) {\n setError(e instanceof Error ? e.message : String(e));\n }\n return lastCount.current;\n },\n loadRows: async () => {\n if (!source) return [];\n try {\n return await source.loadRows();\n } catch (e) {\n setError(e instanceof Error ? e.message : String(e));\n return [];\n }\n },\n markAllSeen: async () => (source ? source.markAllSeen() : []),\n }),\n [source, lang],\n );\n const [state, setState] = useState(shell.getState());\n useEffect(() => shell.subscribe(setState), [shell]);\n useEffect(() => {\n setState(shell.getState());\n void shell.refresh();\n return source?.subscribe?.(() => {\n if (shell.getState().open) void shell.open(shell.getState().anchor);\n else void shell.refresh();\n });\n }, [shell, source]);\n useEffect(() => {\n if (!state.open) return;\n const onKey = (e: KeyboardEvent) => {\n if (e.key === \"Escape\" && shell.escape() === \"close\") e.preventDefault();\n };\n document.addEventListener(\"keydown\", onKey);\n return () => document.removeEventListener(\"keydown\", onKey);\n }, [state.open, shell]);\n\n const label = badgeLabel(state.count);\n const onRow = async (n: NotificationRow) => {\n shell.close();\n if (n.seenAt == null && source) {\n await source.markSeen([n.id]);\n await shell.refresh();\n }\n const target = safeNavigate(n.navigate);\n if (target) {\n if (onNavigate) onNavigate(target);\n else if (typeof window !== \"undefined\") window.location.assign(target);\n }\n };\n const seen = (n: NotificationRow) => n.seenAt != null || state.clearedIds.includes(n.id);\n\n return (\n <div class=\"bas-bell\">\n <button\n type=\"button\"\n class=\"bas-iconbtn\"\n data-testid=\"topbar-notifications\"\n aria-label={t.notifications}\n aria-expanded={state.open}\n onClick={(e: JSX.TargetedMouseEvent<HTMLButtonElement>) => {\n const r = e.currentTarget.getBoundingClientRect();\n void shell.toggle({ top: r.top, right: r.right, bottom: r.bottom, left: r.left, width: r.width, height: r.height } as never);\n }}\n >\n <IconBell />\n {label ? (\n <span class=\"bas-bell__count\" data-testid=\"topbar-notifications-count\">\n {label}\n </span>\n ) : null}\n </button>\n {state.open ? (\n <>\n <div class={\"bas-overlay\" + (mobile ? \" is-dim\" : \"\")} data-testid=\"notifications-backdrop\" onClick={() => shell.close()} />\n <div\n class={\"bas-panel \" + (mobile ? \"bas-panel--sheet\" : \"bas-panel--drop\")}\n role=\"dialog\"\n aria-label={shell.labels.panel}\n data-testid={mobile ? \"notifications-drawer\" : \"notifications-dropdown\"}\n >\n <div class=\"bas-panel__head\">\n <h3>{t.notifications}</h3>\n <button type=\"button\" class=\"bas-link\" data-testid=\"notifications-mark-all\" onClick={() => void shell.markAllSeen()} disabled={!state.count}>\n {shell.labels.markAll}\n </button>\n </div>\n <div class=\"bas-panel__list\" data-testid=\"notifications-list\">\n {error && state.rows.length === 0 ? (\n <p class=\"bas-panel__note is-error\" data-testid=\"notifications-error\">\n {t.couldNotLoad}\n </p>\n ) : state.rows.length === 0 ? (\n <p class=\"bas-panel__note\" data-testid=\"notifications-empty\">\n {shell.labels.empty}\n </p>\n ) : (\n state.rows.map((n) => (\n <button\n type=\"button\"\n key={n.id}\n class={\"bas-note\" + (seen(n) ? \" is-read\" : \"\")}\n data-testid=\"notification-row\"\n data-id={n.id}\n onClick={() => void onRow(n)}\n >\n <span class=\"bas-note__text\">\n <span class=\"bas-note__title\">{n.title}</span>\n {n.body ? <span class=\"bas-note__body\">{n.body}</span> : null}\n <span class=\"bas-note__time\">{relativeTime(n.createdAt, lang)}</span>\n </span>\n {!seen(n) ? <span class=\"bas-note__dot\" /> : null}\n </button>\n ))\n )}\n </div>\n </div>\n </>\n ) : null}\n </div>\n );\n}\n\n// ── User menu ──────────────────────────────────────────────────────────────\n\nexport interface ShellUser {\n name?: string;\n email?: string;\n /** Broberg ID OIDC `picture`. Without it: initials. Never Gravatar (D-1dc849). */\n picture?: string;\n}\nexport interface UserMenuItem {\n id: string;\n label: string;\n icon?: Icon;\n href?: string;\n onSelect?: () => void;\n}\nexport interface UserMenuProps {\n user: ShellUser;\n /** «Konto» → Broberg ID's account page. */\n accountHref?: string;\n items?: UserMenuItem[];\n onSignOut?: () => void | Promise<void>;\n onNavigate?: Navigate;\n /** Show Theme · Palette · Surfaces · Backdrop. Default true. */\n appearance?: boolean;\n lang: Lang;\n}\n\nexport function Avatar({ user, size = 28 }: { user: ShellUser; size?: number }) {\n const [broken, setBroken] = useState(false);\n const style = `width:${size}px;height:${size}px;font-size:${Math.round(size * 0.4)}px`;\n if (user.picture && !broken) {\n return <img class=\"bas-avatar\" style={style} src={user.picture} alt=\"\" referrerpolicy=\"no-referrer\" onError={() => setBroken(true)} data-testid=\"avatar-picture\" />;\n }\n return (\n <span class=\"bas-avatar bas-avatar--initials\" style={style} data-testid=\"avatar-initials\" aria-hidden=\"true\">\n {initials(user.name, user.email)}\n </span>\n );\n}\n\nfunction Segmented<T extends string>(props: { testid: string; value: T; options: readonly (readonly [T, string])[]; onChange: (v: T) => void }) {\n return (\n <div class=\"bas-seg\" data-testid={props.testid} role=\"group\">\n {props.options.map(([v, label]) => (\n <button type=\"button\" key={v} aria-pressed={props.value === v} data-testid={`${props.testid}-${v}`} onClick={() => props.onChange(v)}>\n {label}\n </button>\n ))}\n </div>\n );\n}\n\nexport function UserMenu(p: UserMenuProps) {\n const t = TEXT[p.lang];\n const [open, setOpen] = useState(false);\n const [busy, setBusy] = useState(false);\n const root = useRef<HTMLDivElement>(null);\n const [pref, setPref] = useState<ThemePreference>(() => getPreference());\n const [palette, setPal] = useState<Palette>(() => getPalette());\n const [surfaces, setSurf] = useState<Surfaces>(() => getSurfaces());\n const [backdrop, setBack] = useState<Backdrop>(() => getBackdrop());\n\n useEffect(() => {\n const offs = [\n onThemeChange(() => setPref(getPreference())),\n onPaletteChange(setPal),\n onSurfacesChange(setSurf),\n onBackdropChange(setBack),\n ];\n return () => offs.forEach((off) => off());\n }, []);\n\n useEffect(() => {\n if (!open) return;\n const onDown = (e: MouseEvent) => {\n if (root.current && !root.current.contains(e.target as Node)) setOpen(false);\n };\n const onKey = (e: KeyboardEvent) => e.key === \"Escape\" && setOpen(false);\n document.addEventListener(\"mousedown\", onDown);\n document.addEventListener(\"keydown\", onKey);\n return () => {\n document.removeEventListener(\"mousedown\", onDown);\n document.removeEventListener(\"keydown\", onKey);\n };\n }, [open]);\n\n const firstName = (p.user.name ?? \"\").trim().split(/\\s+/)[0] || p.user.email || \"\";\n const signOut = async () => {\n setBusy(true);\n try {\n await p.onSignOut?.();\n } finally {\n setBusy(false);\n setOpen(false);\n }\n };\n\n return (\n <div class=\"bas-usermenu\" ref={root}>\n <button\n type=\"button\"\n class={\"bas-userbtn\" + (open ? \" is-open\" : \"\")}\n data-testid=\"topbar-user-menu\"\n aria-haspopup=\"menu\"\n aria-expanded={open}\n aria-label={p.user.email ?? p.user.name ?? t.account}\n onClick={() => setOpen((v) => !v)}\n >\n <Avatar user={p.user} />\n <span class=\"bas-userbtn__name\">{firstName}</span>\n </button>\n {open ? (\n <div class=\"bas-menu\" role=\"menu\" data-testid=\"topbar-user-menu-dropdown\">\n <div class=\"bas-menu__who\">\n <Avatar user={p.user} size={36} />\n <div class=\"bas-menu__whotext\">\n {p.user.name ? <div class=\"bas-menu__name\">{p.user.name}</div> : null}\n {p.user.email ? <div class=\"bas-menu__email\">{p.user.email}</div> : null}\n </div>\n </div>\n <div class=\"bas-sep\" />\n {p.accountHref ? (\n <a class=\"bas-mi\" href={p.accountHref} data-testid=\"user-menu-account\" role=\"menuitem\">\n <IconUser />\n <span>{t.account}</span>\n </a>\n ) : null}\n {(p.items ?? []).map((it) =>\n it.href ? (\n <NavLink key={it.id} href={it.href} onNavigate={p.onNavigate} onAfter={() => setOpen(false)} class=\"bas-mi\" data-testid={`user-menu-${it.id}`}>\n {it.icon ?? null}\n <span>{it.label}</span>\n </NavLink>\n ) : (\n <button\n key={it.id}\n type=\"button\"\n class=\"bas-mi\"\n role=\"menuitem\"\n data-testid={`user-menu-${it.id}`}\n onClick={() => {\n setOpen(false);\n it.onSelect?.();\n }}\n >\n {it.icon ?? null}\n <span>{it.label}</span>\n </button>\n ),\n )}\n {p.appearance !== false ? (\n <>\n <div class=\"bas-sep\" />\n <div class=\"bas-prefs\">\n <div class=\"bas-pref\">\n <span>{t.theme}</span>\n <Segmented\n testid=\"user-menu-theme\"\n value={pref as \"light\" | \"dark\" | \"system\"}\n options={[[\"light\", t.light], [\"dark\", t.dark], [\"system\", t.system]] as const}\n onChange={(v) => {\n setPreference(v);\n setPref(v);\n }}\n />\n </div>\n <div class=\"bas-pref\">\n <span>{t.palette}</span>\n <Segmented testid=\"user-menu-palette\" value={palette} options={PALETTES.map((x) => [x, PALETTE_LABELS[x]] as const)} onChange={setPalette} />\n </div>\n <div class=\"bas-pref\">\n <span>{t.surfaces}</span>\n <Segmented testid=\"user-menu-surfaces\" value={surfaces} options={[[\"flat\", t.flat], [\"layered\", t.layered]] as const} onChange={setSurfaces} />\n </div>\n <div class=\"bas-pref\">\n <span>{t.backdrop}</span>\n <Segmented testid=\"user-menu-backdrop\" value={backdrop} options={[[\"neurons\", t.neurons], [\"plain\", t.plain]] as const} onChange={setBackdrop} />\n </div>\n </div>\n </>\n ) : null}\n {p.onSignOut ? (\n <>\n <div class=\"bas-sep\" />\n <button type=\"button\" class=\"bas-mi is-danger\" role=\"menuitem\" data-testid=\"topbar-sign-out\" disabled={busy} onClick={() => void signOut()}>\n <IconLogOut />\n <span>{t.signOut}</span>\n </button>\n </>\n ) : null}\n </div>\n ) : null}\n </div>\n );\n}\n\n// ── Top bar ────────────────────────────────────────────────────────────────\n\nexport interface TopBarProps {\n /** F092.7 — when set, the brand is a link to the app's start page. */\n homeHref?: string;\n /** Called after the brand link was followed (AppShell closes the drawer). */\n onHome?: () => void;\n brand?: ComponentChildren;\n /** Anything app-specific (project switcher, search) between brand and bell. */\n actions?: ComponentChildren;\n /** Drawer mode on a phone: show the hamburger and call this. */\n onOpenMenu?: () => void;\n notifications?: NotificationSource;\n user?: ShellUser;\n userMenu?: Omit<UserMenuProps, \"user\" | \"lang\" | \"onNavigate\">;\n onNavigate?: Navigate;\n lang: Lang;\n}\n\n/** Brand left, actions, then the notification bell and the user menu ALWAYS last, in that order. */\nexport function TopBar(p: TopBarProps) {\n const t = TEXT[p.lang];\n return (\n <header class=\"bas-topbar\" data-testid=\"topbar-root\">\n <div class=\"bas-topbar__inner\">\n {p.onOpenMenu ? (\n <button type=\"button\" class=\"bas-iconbtn bas-hamburger\" data-testid=\"sidebar-toggle\" aria-label={t.openMenu} onClick={p.onOpenMenu}>\n <IconMenu />\n </button>\n ) : null}\n {p.brand ? (\n <div class=\"bas-topbar__brand\">\n {p.homeHref ? (\n <NavLink href={p.homeHref} onNavigate={p.onNavigate} onAfter={p.onHome} class=\"bas-home\" data-testid=\"brand-home\">\n {p.brand}\n </NavLink>\n ) : (\n p.brand\n )}\n </div>\n ) : null}\n {p.actions ? <div class=\"bas-topbar__actions\">{p.actions}</div> : null}\n <div class=\"bas-spacer\" />\n <NotificationBell source={p.notifications} onNavigate={p.onNavigate} lang={p.lang} />\n {p.user ? <UserMenu user={p.user} {...p.userMenu} onNavigate={p.onNavigate} lang={p.lang} /> : null}\n </div>\n </header>\n );\n}\n\n// ── Page header + tabs ─────────────────────────────────────────────────────\n\n/**\n * Optional `title` (0.2.1): inside AppShell the page title already sits in the\n * content header, so a page can use PageHeader for its description and actions\n * alone — no second, and no empty, <h1>.\n */\nexport function PageHeader(p: { eyebrow?: ComponentChildren; title?: ComponentChildren; description?: ComponentChildren; actions?: ComponentChildren }) {\n return (\n <div class=\"bas-pagehead\" data-testid=\"page-header\">\n <div class=\"bas-pagehead__text\">\n {p.eyebrow ? <div class=\"bas-pagehead__eyebrow\">{p.eyebrow}</div> : null}\n {p.title != null && p.title !== \"\" ? <h1 class=\"bas-pagehead__title\">{p.title}</h1> : null}\n {p.description ? <p class=\"bas-pagehead__desc\">{p.description}</p> : null}\n </div>\n {p.actions ? <div class=\"bas-pagehead__actions\">{p.actions}</div> : null}\n </div>\n );\n}\n\nexport interface PageTab {\n id: string;\n label: ComponentChildren;\n /** Path mode: the tab's own route. Query mode: ignored (?tab=id is used). */\n href?: string;\n}\n\n/**\n * Tabs as routes. `mode: \"query\"` puts the tab in `?tab=<id>` on the current\n * path (first tab when absent); `mode: \"path\"` gives each tab its own href.\n */\nexport function PageTabs(p: { tabs: PageTab[]; currentUrl: string; mode?: \"query\" | \"path\"; onNavigate?: Navigate }) {\n const mode = p.mode ?? \"query\";\n const url = new URL(p.currentUrl, \"http://x\");\n const activeId =\n mode === \"query\"\n ? url.searchParams.get(\"tab\") ?? p.tabs[0]?.id\n : p.tabs.find((tab) => tab.href && isActivePath(tab.href, url.pathname))?.id;\n return (\n <div class=\"bas-tabs\" role=\"tablist\" data-testid=\"page-tabs\">\n {p.tabs.map((tab) => {\n let href = tab.href ?? \"\";\n if (mode === \"query\") {\n const u = new URL(url.toString());\n u.searchParams.set(\"tab\", tab.id);\n href = u.pathname + u.search;\n }\n const active = tab.id === activeId;\n return (\n <NavLink key={tab.id} href={href} onNavigate={p.onNavigate} class={\"bas-tab\" + (active ? \" is-active\" : \"\")} data-testid={`page-tab-${tab.id}`} aria-current={active ? \"page\" : undefined}>\n {tab.label}\n </NavLink>\n );\n })}\n </div>\n );\n}\n\n// ── App shell ──────────────────────────────────────────────────────────────\n\nexport interface AppShellProps {\n brand?: ComponentChildren;\n actions?: ComponentChildren;\n groups: PreactNavGroup[];\n footer?: PreactNavItem[];\n currentPath: string;\n onNavigate?: Navigate;\n /** The notification centre's source. The bell is shown either way. */\n notifications?: NotificationSource;\n user?: ShellUser;\n userMenu?: Omit<UserMenuProps, \"user\" | \"lang\" | \"onNavigate\">;\n /** Phone behaviour: a slide-in drawer, or a 60px icon rail. */\n mobile?: \"drawer\" | \"rail\";\n /**\n * F092.6 — desktop fold: \"offcanvas\" hides the sidebar, \"icon\" keeps a 48px\n * icon rail with `brandMark` on top. Default: \"icon\" when `mobile` is \"rail\".\n */\n collapse?: \"offcanvas\" | \"icon\";\n /** The app's logo icon for the top of the icon rail. */\n brandMark?: ComponentChildren;\n /** F092.7 — the app's start page. Brand and brandMark become links to it; on a phone the click closes the drawer. */\n homeHref?: string;\n /** Accessible name for the brandMark link. Default \"Forside\"/\"Home\". */\n homeLabel?: string;\n /**\n * F092.4 — the page title in the content header, after the sidebar button.\n * Absent: the label of the active nav item (a sub-item wins over its parent).\n */\n title?: ComponentChildren;\n /** localStorage key prefix for the folded sidebar, folded groups and open items. */\n storageKey?: string;\n /** Required: the shell ships no default language (see @broberg/notifications/shell). */\n lang: Lang;\n children?: ComponentChildren;\n}\n\nexport function AppShell(p: AppShellProps) {\n const prefix = p.storageKey ?? \"broberg-app-shell\";\n const mode = p.mobile ?? \"drawer\";\n const collapse = p.collapse ?? (mode === \"rail\" ? \"icon\" : \"offcanvas\");\n const [collapsed, setCollapsed] = useState(() => readFlag(`${prefix}.collapsed`, false));\n const [drawer, setDrawer] = useState(false);\n const isMobile = useIsMobile();\n const t = TEXT[p.lang];\n const toggle = () => {\n const next = !collapsed;\n setCollapsed(next);\n writeFlag(`${prefix}.collapsed`, next);\n };\n // F092.4 — ONE sidebar button: the drawer on a phone, the fold on desktop.\n const drawerMode = isMobile && mode === \"drawer\";\n const onTrigger = () => (drawerMode ? setDrawer(!drawer) : toggle());\n const expanded = drawerMode ? drawer : !collapsed;\n const triggerLabel = drawerMode ? (drawer ? t.closeMenu : t.openMenu) : collapsed ? t.expand : t.collapse;\n const heading = p.title ?? activeNavLabel(p.groups, p.footer, p.currentPath);\n return (\n <div class=\"bas-root\" data-testid=\"app-shell\" data-mobile={mode}>\n <TopBar\n brand={p.brand}\n homeHref={p.homeHref}\n onHome={() => setDrawer(false)}\n actions={p.actions}\n notifications={p.notifications}\n user={p.user}\n userMenu={p.userMenu}\n onNavigate={p.onNavigate}\n lang={p.lang}\n />\n <div class=\"bas-row\">\n <Sidebar\n groups={p.groups}\n footer={p.footer}\n currentPath={p.currentPath}\n onNavigate={p.onNavigate}\n collapsed={collapsed}\n collapse={collapse}\n brandMark={p.brandMark}\n homeHref={p.homeHref}\n homeLabel={p.homeLabel}\n mobileOpen={drawer}\n onClose={() => setDrawer(false)}\n mobile={mode}\n header={mode === \"drawer\" ? p.brand : undefined}\n groupsKey={`${prefix}.groups`}\n itemsKey={`${prefix}.items`}\n lang={p.lang}\n />\n <main class=\"bas-main\" data-testid=\"app-content\">\n <div class=\"bas-contenthead\" data-testid=\"content-header\">\n <button\n type=\"button\"\n class=\"bas-iconbtn bas-trigger\"\n data-testid=\"sidebar-trigger\"\n aria-label={triggerLabel}\n aria-expanded={expanded}\n title={triggerLabel}\n onClick={onTrigger}\n >\n <IconPanelLeft />\n </button>\n {heading ? (\n <>\n <span class=\"bas-contenthead__sep\" data-testid=\"content-header-separator\" aria-hidden=\"true\" />\n <h1 class=\"bas-contenthead__title\" data-testid=\"content-header-title\">\n {heading}\n </h1>\n </>\n ) : null}\n </div>\n {p.children}\n </main>\n </div>\n </div>\n );\n}\n"]}
|
package/dist/preact.d.cts
CHANGED
|
@@ -247,9 +247,14 @@ interface TopBarProps {
|
|
|
247
247
|
}
|
|
248
248
|
/** Brand left, actions, then the notification bell and the user menu ALWAYS last, in that order. */
|
|
249
249
|
declare function TopBar(p: TopBarProps): JSX.Element;
|
|
250
|
+
/**
|
|
251
|
+
* Optional `title` (0.2.1): inside AppShell the page title already sits in the
|
|
252
|
+
* content header, so a page can use PageHeader for its description and actions
|
|
253
|
+
* alone — no second, and no empty, <h1>.
|
|
254
|
+
*/
|
|
250
255
|
declare function PageHeader(p: {
|
|
251
256
|
eyebrow?: ComponentChildren;
|
|
252
|
-
title
|
|
257
|
+
title?: ComponentChildren;
|
|
253
258
|
description?: ComponentChildren;
|
|
254
259
|
actions?: ComponentChildren;
|
|
255
260
|
}): JSX.Element;
|
package/dist/preact.d.ts
CHANGED
|
@@ -247,9 +247,14 @@ interface TopBarProps {
|
|
|
247
247
|
}
|
|
248
248
|
/** Brand left, actions, then the notification bell and the user menu ALWAYS last, in that order. */
|
|
249
249
|
declare function TopBar(p: TopBarProps): JSX.Element;
|
|
250
|
+
/**
|
|
251
|
+
* Optional `title` (0.2.1): inside AppShell the page title already sits in the
|
|
252
|
+
* content header, so a page can use PageHeader for its description and actions
|
|
253
|
+
* alone — no second, and no empty, <h1>.
|
|
254
|
+
*/
|
|
250
255
|
declare function PageHeader(p: {
|
|
251
256
|
eyebrow?: ComponentChildren;
|
|
252
|
-
title
|
|
257
|
+
title?: ComponentChildren;
|
|
253
258
|
description?: ComponentChildren;
|
|
254
259
|
actions?: ComponentChildren;
|
|
255
260
|
}): JSX.Element;
|
package/dist/preact.js
CHANGED
|
@@ -726,7 +726,7 @@ function PageHeader(p) {
|
|
|
726
726
|
return /* @__PURE__ */ jsxs("div", { class: "bas-pagehead", "data-testid": "page-header", children: [
|
|
727
727
|
/* @__PURE__ */ jsxs("div", { class: "bas-pagehead__text", children: [
|
|
728
728
|
p.eyebrow ? /* @__PURE__ */ jsx("div", { class: "bas-pagehead__eyebrow", children: p.eyebrow }) : null,
|
|
729
|
-
/* @__PURE__ */ jsx("h1", { class: "bas-pagehead__title", children: p.title }),
|
|
729
|
+
p.title != null && p.title !== "" ? /* @__PURE__ */ jsx("h1", { class: "bas-pagehead__title", children: p.title }) : null,
|
|
730
730
|
p.description ? /* @__PURE__ */ jsx("p", { class: "bas-pagehead__desc", children: p.description }) : null
|
|
731
731
|
] }),
|
|
732
732
|
p.actions ? /* @__PURE__ */ jsx("div", { class: "bas-pagehead__actions", children: p.actions }) : null
|
package/dist/preact.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/preact.tsx"],"names":[],"mappings":"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","file":"preact.js","sourcesContent":["// @broberg/app-shell — the framework-free core of the fleet's app shell (F092).\n//\n// The shell every app in the fleet had been copying: sidebar + top bar +\n// notification bell + user menu. cardmem and trail each had one (\"ported from\n// trail\"), and helpdesk and the appkit starter would have made the third and\n// fourth. This file holds what does not depend on a framework: the navigation\n// data model, the notification contract and its sources, and the small rules\n// both the Preact and React parts must agree on.\n//\n// Christian, 4 Oct 2026: notifications are a STANDARD part of the template, not\n// an optional slot — so the contract and a default source live here, and a new\n// app gets a working notification centre by pointing one URL at its backend.\n\n// ── Navigation ─────────────────────────────────────────────────────────────\n\n/** One sidebar entry. `icon` is whatever your framework renders (an element). */\nexport interface NavItem<Icon = unknown> {\n id: string;\n label: string;\n href: string;\n icon?: Icon;\n /** A count shown on the item (99+ above 99). 0/undefined shows nothing. */\n badge?: number;\n /**\n * Sub-items, ONE level (F092.5). An item with children is a toggle that opens\n * and closes them, not a link; its own `href` is used only to decide whether\n * it is on the current path.\n */\n children?: NavItem<Icon>[];\n}\nexport interface NavGroup<Icon = unknown> {\n label: string;\n items: NavItem<Icon>[];\n}\n\n/**\n * Is this item the current page? Exact match for \"/\", otherwise the path is the\n * item or below it (\"/board/123\" is on \"/board\", \"/boardroom\" is not).\n */\nexport function isActivePath(href: string, currentPath: string): boolean {\n const path = (currentPath.split(/[?#]/)[0] || \"/\").replace(/\\/+$/, \"\") || \"/\";\n const target = (href.split(/[?#]/)[0] || \"/\").replace(/\\/+$/, \"\") || \"/\";\n if (target === \"/\") return path === \"/\";\n return path === target || path.startsWith(target + \"/\");\n}\n\n/**\n * A notification's `navigate` is SERVER DATA, and it ends in `location.assign`.\n * `javascript:` there runs code in the app, so only a same-site path or an\n * http(s) URL is followed; anything else returns null and the row just closes.\n */\nexport function safeNavigate(target: string | null | undefined): string | null {\n if (typeof target !== \"string\") return null;\n const t = target.trim();\n if (t.startsWith(\"/\") && !t.startsWith(\"//\") && !t.startsWith(\"/\\\\\")) return t;\n try {\n const u = new URL(t);\n return u.protocol === \"https:\" || u.protocol === \"http:\" ? u.href : null;\n } catch {\n return null;\n }\n}\n\n/**\n * The label of the nav item the user is on, for the content header (F092.4).\n * Sub-items count, and the most specific match wins: on \"/models/genesis\" a\n * \"Genesis\" child beats its \"Models\" parent.\n */\nexport function activeNavLabel<Icon>(\n groups: NavGroup<Icon>[],\n footer: NavItem<Icon>[] | undefined,\n currentPath: string,\n): string | undefined {\n let best: { label: string; len: number } | undefined;\n const visit = (it: NavItem<Icon>) => {\n if (it.href && isActivePath(it.href, currentPath)) {\n const len = it.href.length;\n if (!best || len > best.len) best = { label: it.label, len };\n }\n it.children?.forEach(visit);\n };\n for (const g of groups) g.items.forEach(visit);\n footer?.forEach(visit);\n return best?.label;\n}\n\n/** \"99+\" above 99, nothing for 0 or less. */\nexport function badgeLabel(n: number | undefined): string | null {\n if (!n || n <= 0) return null;\n return n > 99 ? \"99+\" : String(n);\n}\n\n// ── Persisted UI state ─────────────────────────────────────────────────────\n\n/** Read a boolean flag from localStorage; storage errors read as `fallback`. */\nexport function readFlag(key: string, fallback: boolean): boolean {\n try {\n const v = typeof localStorage === \"undefined\" ? null : localStorage.getItem(key);\n return v === null ? fallback : v === \"1\";\n } catch {\n return fallback;\n }\n}\nexport function writeFlag(key: string, value: boolean): void {\n try {\n if (typeof localStorage !== \"undefined\") localStorage.setItem(key, value ? \"1\" : \"0\");\n } catch {\n /* private mode / quota: the UI still works, it just does not remember */\n }\n}\nexport function readSet(key: string): Set<string> {\n try {\n const raw = typeof localStorage === \"undefined\" ? null : localStorage.getItem(key);\n const v = raw ? (JSON.parse(raw) as unknown) : [];\n return new Set(Array.isArray(v) ? v.filter((x): x is string => typeof x === \"string\") : []);\n } catch {\n return new Set();\n }\n}\nexport function writeSet(key: string, value: Set<string>): void {\n try {\n if (typeof localStorage !== \"undefined\") localStorage.setItem(key, JSON.stringify([...value]));\n } catch {\n /* see writeFlag */\n }\n}\n\n// ── Avatar ─────────────────────────────────────────────────────────────────\n\n/**\n * Two initials for the avatar fallback: first letter of the first and the last\n * word, upper-cased. One word gives one letter; nothing gives \"?\".\n *\n * There is deliberately no Gravatar here (owner decision D-1dc849): the avatar\n * is the Broberg ID `picture`, and without one, initials. Gravatar would send a\n * hash of the user's email to a US service on every render.\n */\nexport function initials(name: string | undefined, email?: string): string {\n const source = (name ?? \"\").trim() || (email ?? \"\").split(\"@\")[0] || \"\";\n const words = source.split(/[\\s._-]+/).filter(Boolean);\n if (words.length === 0) return \"?\";\n const first = words[0]![0] ?? \"\";\n const last = words.length > 1 ? words[words.length - 1]![0] ?? \"\" : \"\";\n return (first + last).toUpperCase() || \"?\";\n}\n\n// ── Notifications ──────────────────────────────────────────────────────────\n//\n// REUSE, NOT A SECOND CONTRACT. The fleet already agreed the notification shape\n// in @broberg/notifications (F074): `NotificationRow` — the same field names\n// @broberg/webpush sends, end to end — and the server core that owns the ONE\n// counting rule. The shell's bell renders that row and drives its panel with\n// that package's `createBellShell`, so a server built on `createNotifications`\n// and this bell speak the same language without an adapter.\n//\n// Christian, 4 Oct 2026: notifications are a STANDARD part of the template. So\n// a source, and a default one, ship here: point one URL at your backend.\n\nimport type { NotificationRow } from \"@broberg/notifications/types\";\nexport type { NotificationRow } from \"@broberg/notifications/types\";\n\n/** Where the bell gets its data. Swap it to point at any backend. */\nexport interface NotificationSource {\n /** The rows to show (newest first). */\n loadRows(): Promise<NotificationRow[]>;\n /** THE count — your server's, which may exclude muted kinds (F074's counting rule). */\n countUnseen(): Promise<number>;\n /** Returns the ids that actually transitioned to seen. */\n markSeen(ids: readonly string[]): Promise<string[]>;\n markAllSeen(): Promise<string[]>;\n /** Called with a callback that re-counts; return an unsubscribe. Optional. */\n subscribe?(onChange: () => void): () => void;\n}\n\n/**\n * The default source: a URL on your own backend, shaped after\n * @broberg/notifications' server core so `createNotifications` sits right\n * behind it.\n *\n * GET {url} → { items: NotificationRow[], unseen: number }\n * POST {url}/seen { ids: string[] } → { clearedIds: string[], count: number }\n * POST {url}/seen-all → { clearedIds: string[], count: number }\n *\n * It re-counts when the window regains focus or the tab becomes visible, and on\n * a timer (default 60 s). A failed GET THROWS — the bell shows «could not\n * load», never an empty list: \"could not fetch\" and \"nothing new\" must not look\n * the same.\n */\nexport function createFetchNotificationSource(opts: {\n url: string;\n fetch?: typeof fetch;\n /** Re-count interval in ms. 0 turns it off. Default 60 000. */\n pollMs?: number;\n credentials?: RequestCredentials;\n}): NotificationSource {\n const base = opts.url.replace(/\\/+$/, \"\");\n const doFetch = (input: string, init?: RequestInit) =>\n (opts.fetch ?? fetch)(input, { credentials: opts.credentials ?? \"include\", ...init });\n const get = async (): Promise<{ items: NotificationRow[]; unseen: number }> => {\n const res = await doFetch(base, { headers: { accept: \"application/json\" } });\n if (!res.ok) throw new Error(`HTTP ${res.status}`);\n const body = (await res.json().catch(() => null)) as { items?: unknown; unseen?: unknown } | null;\n if (!body || !Array.isArray(body.items)) throw new Error(\"response has no items array\");\n const items = body.items as NotificationRow[];\n const unseen = typeof body.unseen === \"number\" ? body.unseen : items.filter((n) => n.seenAt == null).length;\n return { items, unseen };\n };\n const post = async (path: string, body?: unknown): Promise<string[]> => {\n const res = await doFetch(`${base}${path}`, {\n method: \"POST\",\n headers: body === undefined ? undefined : { \"content-type\": \"application/json\" },\n body: body === undefined ? undefined : JSON.stringify(body),\n });\n if (!res.ok) throw new Error(`HTTP ${res.status}`);\n const r = (await res.json().catch(() => ({}))) as { clearedIds?: unknown };\n return Array.isArray(r.clearedIds) ? (r.clearedIds as string[]) : [];\n };\n return {\n loadRows: async () => (await get()).items,\n countUnseen: async () => (await get()).unseen,\n markSeen: (ids) => post(\"/seen\", { ids }),\n markAllSeen: () => post(\"/seen-all\"),\n subscribe(onChange) {\n if (typeof window === \"undefined\") return () => {};\n const onVisible = () => {\n if (document.visibilityState === \"visible\") onChange();\n };\n window.addEventListener(\"focus\", onChange);\n document.addEventListener(\"visibilitychange\", onVisible);\n const ms = opts.pollMs ?? 60_000;\n const timer = ms > 0 ? setInterval(onChange, ms) : null;\n return () => {\n window.removeEventListener(\"focus\", onChange);\n document.removeEventListener(\"visibilitychange\", onVisible);\n if (timer) clearInterval(timer);\n };\n },\n };\n}\n\n/** An in-memory source for demos and tests. */\nexport function createMemoryNotificationSource(initial: NotificationRow[] = []): NotificationSource & {\n push(n: NotificationRow): void;\n rows(): NotificationRow[];\n} {\n let rows = initial.map((n) => ({ ...n }));\n const listeners = new Set<() => void>();\n const emit = () => listeners.forEach((l) => l());\n const mark = (pred: (n: NotificationRow) => boolean): string[] => {\n const now = Date.now();\n const cleared: string[] = [];\n rows = rows.map((n) => {\n if (n.seenAt == null && pred(n)) {\n cleared.push(n.id);\n return { ...n, seenAt: now };\n }\n return n;\n });\n if (cleared.length) emit();\n return cleared;\n };\n return {\n loadRows: async () => rows.map((n) => ({ ...n })),\n countUnseen: async () => rows.filter((n) => n.seenAt == null).length,\n markSeen: async (ids) => mark((n) => ids.includes(n.id)),\n markAllSeen: async () => mark(() => true),\n subscribe(onChange) {\n listeners.add(onChange);\n return () => listeners.delete(onChange);\n },\n push(n) {\n rows = [n, ...rows];\n emit();\n },\n rows: () => rows.map((n) => ({ ...n })),\n };\n}\n\n/** \"nu\", \"5 min\", \"3 t\", \"i går\", \"4 d\" (da) or the English equivalents. */\nexport function relativeTime(ts: string | number, lang: \"da\" | \"en\", now = Date.now()): string {\n const ms = typeof ts === \"number\" ? ts : Date.parse(ts);\n if (!Number.isFinite(ms)) return \"\";\n const m = Math.floor((now - ms) / 60_000);\n if (m < 1) return lang === \"da\" ? \"nu\" : \"now\";\n if (m < 60) return `${m} min`;\n const h = Math.floor(m / 60);\n if (h < 24) return lang === \"da\" ? `${h} t` : `${h} h`;\n const d = Math.floor(h / 24);\n if (d === 1) return lang === \"da\" ? \"i går\" : \"yesterday\";\n return `${d} d`;\n}\n\n// ── Text ───────────────────────────────────────────────────────────────────\n\nexport const TEXT = {\n da: {\n openMenu: \"Åbn menu\",\n closeMenu: \"Luk menu\",\n home: \"Forside\",\n collapse: \"Skjul sidemenu\",\n expand: \"Vis sidemenu\",\n notifications: \"Notifikationer\",\n markAllRead: \"Markér alle læst\",\n noNotifications: \"Ingen notifikationer endnu.\",\n couldNotLoad: \"Kunne ikke hente notifikationer.\",\n seeAll: \"Vis alle\",\n close: \"Luk\",\n account: \"Konto\",\n signOut: \"Log ud\",\n theme: \"Tema\",\n light: \"Lys\",\n dark: \"Mørk\",\n system: \"System\",\n palette: \"Palet\",\n surfaces: \"Flader\",\n flat: \"Flade\",\n layered: \"Lag\",\n backdrop: \"Baggrund\",\n neurons: \"Neuroner\",\n plain: \"Ren\",\n },\n en: {\n openMenu: \"Open menu\",\n closeMenu: \"Close menu\",\n home: \"Home\",\n collapse: \"Hide sidebar\",\n expand: \"Show sidebar\",\n notifications: \"Notifications\",\n markAllRead: \"Mark all read\",\n noNotifications: \"No notifications yet.\",\n couldNotLoad: \"Could not load notifications.\",\n seeAll: \"See all\",\n close: \"Close\",\n account: \"Account\",\n signOut: \"Sign out\",\n theme: \"Theme\",\n light: \"Light\",\n dark: \"Dark\",\n system: \"System\",\n palette: \"Palette\",\n surfaces: \"Surfaces\",\n flat: \"Flat\",\n layered: \"Layered\",\n backdrop: \"Backdrop\",\n neurons: \"Neurons\",\n plain: \"Plain\",\n },\n} as const;\nexport type Lang = keyof typeof TEXT;\n","/** @jsxImportSource preact */\n// @broberg/app-shell/preact — the fleet's app shell for Stack B (F092).\n//\n// Lifted in shape from cardmem (apps/web/src/components/ui: top-nav, app-sidebar,\n// notification-bell, user-menu, page-header, page-tabs; origin/main af80f192)\n// and trail (the original), rewritten as props-in components: nothing here\n// knows about any app's auth, router or data. Styling is css/app-shell.css,\n// on @broberg/theme's tokens, so every palette × light/dark × flat/layered works.\n//\n// Use the whole thing:\n// <AppShell brand={…} groups={…} currentPath={path} user={…} notifications={source}\n// accountHref=\"https://id.broberg.ai/account\" onSignOut={…}>{page}</AppShell>\n// or compose the parts (Sidebar, TopBar, NotificationBell, UserMenu,\n// PageHeader, PageTabs) in your own layout.\n\nimport type { ComponentChildren, JSX } from \"preact\";\nimport { useEffect, useMemo, useRef, useState } from \"preact/hooks\";\nimport { createBellShell } from \"@broberg/notifications/shell\";\nimport {\n getBackdrop,\n getPalette,\n getPreference,\n getSurfaces,\n onBackdropChange,\n onPaletteChange,\n onSurfacesChange,\n onThemeChange,\n PALETTE_LABELS,\n PALETTES,\n setBackdrop,\n setPalette,\n setPreference,\n setSurfaces,\n type Backdrop,\n type Palette,\n type Surfaces,\n type ThemePreference,\n} from \"@broberg/theme\";\nimport {\n activeNavLabel,\n badgeLabel,\n initials,\n isActivePath,\n readFlag,\n readSet,\n relativeTime,\n safeNavigate,\n TEXT,\n writeFlag,\n writeSet,\n type Lang,\n type NavGroup,\n type NavItem,\n type NotificationRow,\n type NotificationSource,\n} from \"./index\";\n\nexport * from \"./index\";\n\ntype Icon = ComponentChildren;\nexport type PreactNavItem = NavItem<Icon>;\nexport type PreactNavGroup = NavGroup<Icon>;\n/** Called instead of a full page load when given. Return false to let the browser navigate. */\nexport type Navigate = (href: string) => void;\n\nconst MOBILE_QUERY = \"(max-width: 767px)\";\n\n/** True below 768px. Follows the window as it resizes. */\nexport function useIsMobile(): boolean {\n const get = () => typeof window !== \"undefined\" && typeof window.matchMedia === \"function\" && window.matchMedia(MOBILE_QUERY).matches;\n const [mobile, setMobile] = useState(get);\n useEffect(() => {\n if (typeof window === \"undefined\" || typeof window.matchMedia !== \"function\") return;\n const mq = window.matchMedia(MOBILE_QUERY);\n const on = () => setMobile(mq.matches);\n mq.addEventListener?.(\"change\", on);\n return () => mq.removeEventListener?.(\"change\", on);\n }, []);\n return mobile;\n}\n\n/** An <a> that hands the click to `onNavigate` (SPA) when given, else a normal link. */\nfunction NavLink(props: {\n href: string;\n onNavigate?: Navigate;\n onAfter?: () => void;\n class?: string;\n children: ComponentChildren;\n \"data-testid\"?: string;\n \"aria-current\"?: \"page\";\n title?: string;\n}) {\n const { href, onNavigate, onAfter, children, ...rest } = props;\n return (\n <a\n {...rest}\n href={href}\n onClick={(e: JSX.TargetedMouseEvent<HTMLAnchorElement>) => {\n if (onNavigate && !e.metaKey && !e.ctrlKey && !e.shiftKey && e.button === 0) {\n e.preventDefault();\n onNavigate(href);\n }\n onAfter?.();\n }}\n >\n {children}\n </a>\n );\n}\n\n// ── Icons (inline, so the package has no icon dependency) ─────────────────\nconst svg = (d: ComponentChildren, size = 18) => (\n <svg viewBox=\"0 0 24 24\" width={size} height={size} fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.9\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\">\n {d}\n </svg>\n);\nconst IconMenu = () => svg(<path d=\"M4 6h16M4 12h16M4 18h16\" />, 20);\nconst IconChevron = ({ open }: { open?: boolean }) => (\n <span class={\"bas-chev\" + (open ? \" is-open\" : \"\")}>{svg(<path d=\"m9 18 6-6-6-6\" />, 12)}</span>\n);\n// lucide \"panel-left\" (ISC), the exact icon in shadcn's SidebarTrigger (F092.4).\nconst IconPanelLeft = () => svg(<><rect width=\"18\" height=\"18\" x=\"3\" y=\"3\" rx=\"2\" /><path d=\"M9 3v18\" /></>, 16);\nconst IconBell = () => svg(<><path d=\"M6 8a6 6 0 0 1 12 0c0 7 3 9 3 9H3s3-2 3-9\" /><path d=\"M10.3 21a1.94 1.94 0 0 0 3.4 0\" /></>, 19);\nconst IconLogOut = () => svg(<><path d=\"M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4\" /><path d=\"m16 17 5-5-5-5\" /><path d=\"M21 12H9\" /></>, 14);\nconst IconUser = () => svg(<><circle cx=\"12\" cy=\"8\" r=\"4\" /><path d=\"M4 21a8 8 0 0 1 16 0\" /></>, 14);\n\n// ── Sidebar ────────────────────────────────────────────────────────────────\n\nexport interface SidebarProps {\n groups: PreactNavGroup[];\n footer?: PreactNavItem[];\n currentPath: string;\n onNavigate?: Navigate;\n /** Desktop: is the sidebar folded (to nothing, or to the icon rail — see `collapse`). */\n collapsed?: boolean;\n /**\n * F092.6 — what \"folded\" means on desktop, as shadcn's `collapsible`:\n * \"offcanvas\" hides the sidebar, \"icon\" keeps a 48px rail of item icons with\n * `brandMark` on top. Default: \"icon\" when `mobile` is \"rail\", else \"offcanvas\".\n */\n collapse?: \"offcanvas\" | \"icon\";\n /** The app's logo icon, shown at the top of the icon rail. */\n brandMark?: ComponentChildren;\n /** F092.7 — the app's start page: `header` and `brandMark` become links to it. */\n homeHref?: string;\n /** Accessible name of the brandMark link (it has no visible text). Default \"Forside\"/\"Home\". */\n homeLabel?: string;\n /** Phone, drawer mode: is the drawer open. */\n mobileOpen?: boolean;\n onClose?: () => void;\n mobile?: \"drawer\" | \"rail\";\n /** Shown at the top of the sidebar (e.g. the brand on a phone). */\n header?: ComponentChildren;\n /** localStorage key for which groups are folded. */\n groupsKey?: string;\n /** localStorage key for which items with children are open (F092.5). */\n itemsKey?: string;\n lang: Lang;\n}\n\nexport function Sidebar(p: SidebarProps) {\n const key = p.groupsKey ?? \"broberg-app-shell.groups\";\n const itemsKey = p.itemsKey ?? \"broberg-app-shell.items\";\n const mode = p.mobile ?? \"drawer\";\n const collapseMode = p.collapse ?? (mode === \"rail\" ? \"icon\" : \"offcanvas\");\n const isMobile = useIsMobile();\n // The rail: on a phone in rail mode, or on desktop when folded to icons.\n const railed = isMobile ? mode === \"rail\" : !!p.collapsed && collapseMode === \"icon\";\n\n const [folded, setFolded] = useState<Set<string>>(() => readSet(key));\n const toggleGroup = (label: string) => {\n const next = new Set(folded);\n next.has(label) ? next.delete(label) : next.add(label);\n setFolded(next);\n writeSet(key, next);\n };\n\n const all = [...p.groups.flatMap((g) => g.items), ...(p.footer ?? [])];\n const childActive = (it: PreactNavItem) => !!it.children?.some((c) => isActivePath(c.href, p.currentPath));\n // Open = what the user left open, plus any parent of the page they are on.\n const [openItems, setOpenItems] = useState<Set<string>>(() => {\n const s = readSet(itemsKey);\n for (const it of all) if (childActive(it)) s.add(it.id);\n return s;\n });\n const toggleItem = (id: string) => {\n const next = new Set(openItems);\n next.has(id) ? next.delete(id) : next.add(id);\n setOpenItems(next);\n writeSet(itemsKey, next);\n };\n\n // F092.6 — the rail's flyout for an item with children.\n const [flyout, setFlyout] = useState<{ id: string; top: number; left: number } | null>(null);\n const flyoutRef = useRef<HTMLDivElement>(null);\n useEffect(() => {\n if (!flyout) return;\n const onKey = (e: KeyboardEvent) => {\n if (e.key === \"Escape\") setFlyout(null);\n };\n const onDown = (e: MouseEvent) => {\n const t = e.target as Node | null;\n if (flyoutRef.current && t && flyoutRef.current.contains(t)) return;\n if (t instanceof Element && t.closest(`[data-flyout-for=\"${flyout.id}\"]`)) return;\n setFlyout(null);\n };\n document.addEventListener(\"keydown\", onKey);\n document.addEventListener(\"mousedown\", onDown);\n return () => {\n document.removeEventListener(\"keydown\", onKey);\n document.removeEventListener(\"mousedown\", onDown);\n };\n }, [flyout]);\n useEffect(() => {\n if (!railed) setFlyout(null);\n }, [railed]);\n\n const close = () => {\n setFlyout(null);\n p.onClose?.();\n };\n\n const leaf = (it: PreactNavItem, sub = false) => {\n const active = isActivePath(it.href, p.currentPath);\n const badge = badgeLabel(it.badge);\n return (\n <NavLink\n key={it.id}\n href={it.href}\n onNavigate={p.onNavigate}\n onAfter={close}\n class={\"bas-item\" + (sub ? \" bas-item--sub\" : \"\") + (active ? \" is-active\" : \"\")}\n data-testid={`sidebar-item-${it.id}`}\n aria-current={active ? \"page\" : undefined}\n aria-label={railed && !sub ? it.label : undefined}\n title={it.label}\n >\n {active && !sub ? <span class=\"bas-item__bar\" /> : null}\n {it.icon ? <span class=\"bas-item__icon\">{it.icon}</span> : null}\n <span class=\"bas-item__label\">{it.label}</span>\n {badge ? <span class=\"bas-item__count\" data-testid={`sidebar-badge-${it.id}`}>{badge}</span> : null}\n </NavLink>\n );\n };\n\n const parent = (it: PreactNavItem) => {\n const children = it.children!;\n const onPage = childActive(it) || isActivePath(it.href, p.currentPath);\n const open = railed ? flyout?.id === it.id : openItems.has(it.id);\n const onClick = (e: JSX.TargetedMouseEvent<HTMLButtonElement>) => {\n if (!railed) return toggleItem(it.id);\n if (flyout?.id === it.id) return setFlyout(null);\n const r = e.currentTarget.getBoundingClientRect();\n setFlyout({ id: it.id, top: r.top, left: r.right + 6 });\n };\n return (\n <div class=\"bas-itemgroup\" key={it.id}>\n <button\n type=\"button\"\n class={\"bas-item bas-item--parent\" + (onPage ? \" is-parent-active\" : \"\")}\n data-testid={`sidebar-item-${it.id}-toggle`}\n data-flyout-for={it.id}\n aria-expanded={open}\n aria-label={railed ? it.label : undefined}\n title={it.label}\n onClick={onClick}\n >\n {onPage && railed ? <span class=\"bas-item__bar\" /> : null}\n {it.icon ? <span class=\"bas-item__icon\">{it.icon}</span> : null}\n <span class=\"bas-item__label\">{it.label}</span>\n <span class=\"bas-item__chev\">\n <IconChevron open={open} />\n </span>\n </button>\n {!railed && open ? <div class=\"bas-sub\">{children.map((c) => leaf(c, true))}</div> : null}\n {railed && flyout?.id === it.id ? (\n <div\n ref={flyoutRef}\n class=\"bas-flyout\"\n data-testid={`sidebar-flyout-${it.id}`}\n role=\"menu\"\n aria-label={it.label}\n style={{ top: `${flyout.top}px`, left: `${flyout.left}px` }}\n >\n <div class=\"bas-flyout__title\">{it.label}</div>\n {children.map((c) => leaf(c, true))}\n </div>\n ) : null}\n </div>\n );\n };\n\n const item = (it: PreactNavItem) => (it.children?.length ? parent(it) : leaf(it));\n\n return (\n <>\n {mode === \"drawer\" ? (\n <div class={\"bas-backdrop\" + (p.mobileOpen ? \" is-open\" : \"\")} data-testid=\"sidebar-backdrop\" onClick={close} />\n ) : null}\n <aside\n class={\n \"bas-sidebar\" +\n ` is-mobile-${mode}` +\n (p.mobileOpen ? \" is-open\" : \"\") +\n (p.collapsed ? \" is-collapsed\" : \"\") +\n (railed ? \" is-railed\" : \"\")\n }\n data-testid=\"sidebar-root\"\n data-mobile={mode}\n data-collapse={collapseMode}\n aria-label=\"Navigation\"\n >\n {p.header || p.brandMark ? (\n <div class=\"bas-sidebar__head\">\n {p.header ? (\n <div class=\"bas-sidebar__brand\">\n {p.homeHref ? (\n <NavLink href={p.homeHref} onNavigate={p.onNavigate} onAfter={close} class=\"bas-home\" data-testid=\"sidebar-brand-home\">\n {p.header}\n </NavLink>\n ) : (\n p.header\n )}\n </div>\n ) : null}\n {p.brandMark ? (\n <div class=\"bas-sidebar__mark\" data-testid=\"sidebar-brand-mark\">\n {p.homeHref ? (\n <NavLink\n href={p.homeHref}\n onNavigate={p.onNavigate}\n onAfter={close}\n class=\"bas-home\"\n data-testid=\"brand-mark-home\"\n aria-label={p.homeLabel ?? TEXT[p.lang].home}\n title={p.homeLabel ?? TEXT[p.lang].home}\n >\n {p.brandMark}\n </NavLink>\n ) : (\n p.brandMark\n )}\n </div>\n ) : null}\n </div>\n ) : null}\n <nav class=\"bas-sidebar__nav\">\n {p.groups.map((g) => {\n const open = railed || !folded.has(g.label);\n const slug = g.label.toLowerCase().replace(/[^a-z0-9]+/g, \"-\");\n return (\n <div class=\"bas-group\" key={g.label}>\n <button type=\"button\" class=\"bas-group__label\" data-testid={`sidebar-group-${slug}`} aria-expanded={open} onClick={() => toggleGroup(g.label)}>\n <IconChevron open={open} />\n <span>{g.label}</span>\n </button>\n {open ? g.items.map(item) : null}\n </div>\n );\n })}\n </nav>\n {p.footer?.length ? <div class=\"bas-sidebar__foot\">{p.footer.map(item)}</div> : null}\n </aside>\n </>\n );\n}\n\n// ── Notification bell ──────────────────────────────────────────────────────\n//\n// Driven by @broberg/notifications' createBellShell: one count however many\n// bells, Escape acts on the innermost layer, and the ids \"mark all read\"\n// actually cleared are held for the visit. This component is only the DOM.\n\nexport interface NotificationBellProps {\n /** Where the data comes from. Absent: the bell is still there, with an empty list. */\n source?: NotificationSource;\n onNavigate?: Navigate;\n /** Required on purpose: a default would make \"nobody chose\" look like a choice. */\n lang: Lang;\n}\n\nexport function NotificationBell({ source, onNavigate, lang }: NotificationBellProps) {\n const t = TEXT[lang];\n const mobile = useIsMobile();\n const [error, setError] = useState<string | null>(null);\n const lastCount = useRef(0);\n const shell = useMemo(\n () =>\n createBellShell({\n labels: { bell: t.notifications, panel: t.notifications, markAll: t.markAllRead, seeAll: t.seeAll, empty: t.noNotifications, close: t.close },\n countUnseen: async () => {\n if (!source) return 0;\n try {\n lastCount.current = await source.countUnseen();\n setError(null);\n } catch (e) {\n setError(e instanceof Error ? e.message : String(e));\n }\n return lastCount.current;\n },\n loadRows: async () => {\n if (!source) return [];\n try {\n return await source.loadRows();\n } catch (e) {\n setError(e instanceof Error ? e.message : String(e));\n return [];\n }\n },\n markAllSeen: async () => (source ? source.markAllSeen() : []),\n }),\n [source, lang],\n );\n const [state, setState] = useState(shell.getState());\n useEffect(() => shell.subscribe(setState), [shell]);\n useEffect(() => {\n setState(shell.getState());\n void shell.refresh();\n return source?.subscribe?.(() => {\n if (shell.getState().open) void shell.open(shell.getState().anchor);\n else void shell.refresh();\n });\n }, [shell, source]);\n useEffect(() => {\n if (!state.open) return;\n const onKey = (e: KeyboardEvent) => {\n if (e.key === \"Escape\" && shell.escape() === \"close\") e.preventDefault();\n };\n document.addEventListener(\"keydown\", onKey);\n return () => document.removeEventListener(\"keydown\", onKey);\n }, [state.open, shell]);\n\n const label = badgeLabel(state.count);\n const onRow = async (n: NotificationRow) => {\n shell.close();\n if (n.seenAt == null && source) {\n await source.markSeen([n.id]);\n await shell.refresh();\n }\n const target = safeNavigate(n.navigate);\n if (target) {\n if (onNavigate) onNavigate(target);\n else if (typeof window !== \"undefined\") window.location.assign(target);\n }\n };\n const seen = (n: NotificationRow) => n.seenAt != null || state.clearedIds.includes(n.id);\n\n return (\n <div class=\"bas-bell\">\n <button\n type=\"button\"\n class=\"bas-iconbtn\"\n data-testid=\"topbar-notifications\"\n aria-label={t.notifications}\n aria-expanded={state.open}\n onClick={(e: JSX.TargetedMouseEvent<HTMLButtonElement>) => {\n const r = e.currentTarget.getBoundingClientRect();\n void shell.toggle({ top: r.top, right: r.right, bottom: r.bottom, left: r.left, width: r.width, height: r.height } as never);\n }}\n >\n <IconBell />\n {label ? (\n <span class=\"bas-bell__count\" data-testid=\"topbar-notifications-count\">\n {label}\n </span>\n ) : null}\n </button>\n {state.open ? (\n <>\n <div class={\"bas-overlay\" + (mobile ? \" is-dim\" : \"\")} data-testid=\"notifications-backdrop\" onClick={() => shell.close()} />\n <div\n class={\"bas-panel \" + (mobile ? \"bas-panel--sheet\" : \"bas-panel--drop\")}\n role=\"dialog\"\n aria-label={shell.labels.panel}\n data-testid={mobile ? \"notifications-drawer\" : \"notifications-dropdown\"}\n >\n <div class=\"bas-panel__head\">\n <h3>{t.notifications}</h3>\n <button type=\"button\" class=\"bas-link\" data-testid=\"notifications-mark-all\" onClick={() => void shell.markAllSeen()} disabled={!state.count}>\n {shell.labels.markAll}\n </button>\n </div>\n <div class=\"bas-panel__list\" data-testid=\"notifications-list\">\n {error && state.rows.length === 0 ? (\n <p class=\"bas-panel__note is-error\" data-testid=\"notifications-error\">\n {t.couldNotLoad}\n </p>\n ) : state.rows.length === 0 ? (\n <p class=\"bas-panel__note\" data-testid=\"notifications-empty\">\n {shell.labels.empty}\n </p>\n ) : (\n state.rows.map((n) => (\n <button\n type=\"button\"\n key={n.id}\n class={\"bas-note\" + (seen(n) ? \" is-read\" : \"\")}\n data-testid=\"notification-row\"\n data-id={n.id}\n onClick={() => void onRow(n)}\n >\n <span class=\"bas-note__text\">\n <span class=\"bas-note__title\">{n.title}</span>\n {n.body ? <span class=\"bas-note__body\">{n.body}</span> : null}\n <span class=\"bas-note__time\">{relativeTime(n.createdAt, lang)}</span>\n </span>\n {!seen(n) ? <span class=\"bas-note__dot\" /> : null}\n </button>\n ))\n )}\n </div>\n </div>\n </>\n ) : null}\n </div>\n );\n}\n\n// ── User menu ──────────────────────────────────────────────────────────────\n\nexport interface ShellUser {\n name?: string;\n email?: string;\n /** Broberg ID OIDC `picture`. Without it: initials. Never Gravatar (D-1dc849). */\n picture?: string;\n}\nexport interface UserMenuItem {\n id: string;\n label: string;\n icon?: Icon;\n href?: string;\n onSelect?: () => void;\n}\nexport interface UserMenuProps {\n user: ShellUser;\n /** «Konto» → Broberg ID's account page. */\n accountHref?: string;\n items?: UserMenuItem[];\n onSignOut?: () => void | Promise<void>;\n onNavigate?: Navigate;\n /** Show Theme · Palette · Surfaces · Backdrop. Default true. */\n appearance?: boolean;\n lang: Lang;\n}\n\nexport function Avatar({ user, size = 28 }: { user: ShellUser; size?: number }) {\n const [broken, setBroken] = useState(false);\n const style = `width:${size}px;height:${size}px;font-size:${Math.round(size * 0.4)}px`;\n if (user.picture && !broken) {\n return <img class=\"bas-avatar\" style={style} src={user.picture} alt=\"\" referrerpolicy=\"no-referrer\" onError={() => setBroken(true)} data-testid=\"avatar-picture\" />;\n }\n return (\n <span class=\"bas-avatar bas-avatar--initials\" style={style} data-testid=\"avatar-initials\" aria-hidden=\"true\">\n {initials(user.name, user.email)}\n </span>\n );\n}\n\nfunction Segmented<T extends string>(props: { testid: string; value: T; options: readonly (readonly [T, string])[]; onChange: (v: T) => void }) {\n return (\n <div class=\"bas-seg\" data-testid={props.testid} role=\"group\">\n {props.options.map(([v, label]) => (\n <button type=\"button\" key={v} aria-pressed={props.value === v} data-testid={`${props.testid}-${v}`} onClick={() => props.onChange(v)}>\n {label}\n </button>\n ))}\n </div>\n );\n}\n\nexport function UserMenu(p: UserMenuProps) {\n const t = TEXT[p.lang];\n const [open, setOpen] = useState(false);\n const [busy, setBusy] = useState(false);\n const root = useRef<HTMLDivElement>(null);\n const [pref, setPref] = useState<ThemePreference>(() => getPreference());\n const [palette, setPal] = useState<Palette>(() => getPalette());\n const [surfaces, setSurf] = useState<Surfaces>(() => getSurfaces());\n const [backdrop, setBack] = useState<Backdrop>(() => getBackdrop());\n\n useEffect(() => {\n const offs = [\n onThemeChange(() => setPref(getPreference())),\n onPaletteChange(setPal),\n onSurfacesChange(setSurf),\n onBackdropChange(setBack),\n ];\n return () => offs.forEach((off) => off());\n }, []);\n\n useEffect(() => {\n if (!open) return;\n const onDown = (e: MouseEvent) => {\n if (root.current && !root.current.contains(e.target as Node)) setOpen(false);\n };\n const onKey = (e: KeyboardEvent) => e.key === \"Escape\" && setOpen(false);\n document.addEventListener(\"mousedown\", onDown);\n document.addEventListener(\"keydown\", onKey);\n return () => {\n document.removeEventListener(\"mousedown\", onDown);\n document.removeEventListener(\"keydown\", onKey);\n };\n }, [open]);\n\n const firstName = (p.user.name ?? \"\").trim().split(/\\s+/)[0] || p.user.email || \"\";\n const signOut = async () => {\n setBusy(true);\n try {\n await p.onSignOut?.();\n } finally {\n setBusy(false);\n setOpen(false);\n }\n };\n\n return (\n <div class=\"bas-usermenu\" ref={root}>\n <button\n type=\"button\"\n class={\"bas-userbtn\" + (open ? \" is-open\" : \"\")}\n data-testid=\"topbar-user-menu\"\n aria-haspopup=\"menu\"\n aria-expanded={open}\n aria-label={p.user.email ?? p.user.name ?? t.account}\n onClick={() => setOpen((v) => !v)}\n >\n <Avatar user={p.user} />\n <span class=\"bas-userbtn__name\">{firstName}</span>\n </button>\n {open ? (\n <div class=\"bas-menu\" role=\"menu\" data-testid=\"topbar-user-menu-dropdown\">\n <div class=\"bas-menu__who\">\n <Avatar user={p.user} size={36} />\n <div class=\"bas-menu__whotext\">\n {p.user.name ? <div class=\"bas-menu__name\">{p.user.name}</div> : null}\n {p.user.email ? <div class=\"bas-menu__email\">{p.user.email}</div> : null}\n </div>\n </div>\n <div class=\"bas-sep\" />\n {p.accountHref ? (\n <a class=\"bas-mi\" href={p.accountHref} data-testid=\"user-menu-account\" role=\"menuitem\">\n <IconUser />\n <span>{t.account}</span>\n </a>\n ) : null}\n {(p.items ?? []).map((it) =>\n it.href ? (\n <NavLink key={it.id} href={it.href} onNavigate={p.onNavigate} onAfter={() => setOpen(false)} class=\"bas-mi\" data-testid={`user-menu-${it.id}`}>\n {it.icon ?? null}\n <span>{it.label}</span>\n </NavLink>\n ) : (\n <button\n key={it.id}\n type=\"button\"\n class=\"bas-mi\"\n role=\"menuitem\"\n data-testid={`user-menu-${it.id}`}\n onClick={() => {\n setOpen(false);\n it.onSelect?.();\n }}\n >\n {it.icon ?? null}\n <span>{it.label}</span>\n </button>\n ),\n )}\n {p.appearance !== false ? (\n <>\n <div class=\"bas-sep\" />\n <div class=\"bas-prefs\">\n <div class=\"bas-pref\">\n <span>{t.theme}</span>\n <Segmented\n testid=\"user-menu-theme\"\n value={pref as \"light\" | \"dark\" | \"system\"}\n options={[[\"light\", t.light], [\"dark\", t.dark], [\"system\", t.system]] as const}\n onChange={(v) => {\n setPreference(v);\n setPref(v);\n }}\n />\n </div>\n <div class=\"bas-pref\">\n <span>{t.palette}</span>\n <Segmented testid=\"user-menu-palette\" value={palette} options={PALETTES.map((x) => [x, PALETTE_LABELS[x]] as const)} onChange={setPalette} />\n </div>\n <div class=\"bas-pref\">\n <span>{t.surfaces}</span>\n <Segmented testid=\"user-menu-surfaces\" value={surfaces} options={[[\"flat\", t.flat], [\"layered\", t.layered]] as const} onChange={setSurfaces} />\n </div>\n <div class=\"bas-pref\">\n <span>{t.backdrop}</span>\n <Segmented testid=\"user-menu-backdrop\" value={backdrop} options={[[\"neurons\", t.neurons], [\"plain\", t.plain]] as const} onChange={setBackdrop} />\n </div>\n </div>\n </>\n ) : null}\n {p.onSignOut ? (\n <>\n <div class=\"bas-sep\" />\n <button type=\"button\" class=\"bas-mi is-danger\" role=\"menuitem\" data-testid=\"topbar-sign-out\" disabled={busy} onClick={() => void signOut()}>\n <IconLogOut />\n <span>{t.signOut}</span>\n </button>\n </>\n ) : null}\n </div>\n ) : null}\n </div>\n );\n}\n\n// ── Top bar ────────────────────────────────────────────────────────────────\n\nexport interface TopBarProps {\n /** F092.7 — when set, the brand is a link to the app's start page. */\n homeHref?: string;\n /** Called after the brand link was followed (AppShell closes the drawer). */\n onHome?: () => void;\n brand?: ComponentChildren;\n /** Anything app-specific (project switcher, search) between brand and bell. */\n actions?: ComponentChildren;\n /** Drawer mode on a phone: show the hamburger and call this. */\n onOpenMenu?: () => void;\n notifications?: NotificationSource;\n user?: ShellUser;\n userMenu?: Omit<UserMenuProps, \"user\" | \"lang\" | \"onNavigate\">;\n onNavigate?: Navigate;\n lang: Lang;\n}\n\n/** Brand left, actions, then the notification bell and the user menu ALWAYS last, in that order. */\nexport function TopBar(p: TopBarProps) {\n const t = TEXT[p.lang];\n return (\n <header class=\"bas-topbar\" data-testid=\"topbar-root\">\n <div class=\"bas-topbar__inner\">\n {p.onOpenMenu ? (\n <button type=\"button\" class=\"bas-iconbtn bas-hamburger\" data-testid=\"sidebar-toggle\" aria-label={t.openMenu} onClick={p.onOpenMenu}>\n <IconMenu />\n </button>\n ) : null}\n {p.brand ? (\n <div class=\"bas-topbar__brand\">\n {p.homeHref ? (\n <NavLink href={p.homeHref} onNavigate={p.onNavigate} onAfter={p.onHome} class=\"bas-home\" data-testid=\"brand-home\">\n {p.brand}\n </NavLink>\n ) : (\n p.brand\n )}\n </div>\n ) : null}\n {p.actions ? <div class=\"bas-topbar__actions\">{p.actions}</div> : null}\n <div class=\"bas-spacer\" />\n <NotificationBell source={p.notifications} onNavigate={p.onNavigate} lang={p.lang} />\n {p.user ? <UserMenu user={p.user} {...p.userMenu} onNavigate={p.onNavigate} lang={p.lang} /> : null}\n </div>\n </header>\n );\n}\n\n// ── Page header + tabs ─────────────────────────────────────────────────────\n\nexport function PageHeader(p: { eyebrow?: ComponentChildren; title: ComponentChildren; description?: ComponentChildren; actions?: ComponentChildren }) {\n return (\n <div class=\"bas-pagehead\" data-testid=\"page-header\">\n <div class=\"bas-pagehead__text\">\n {p.eyebrow ? <div class=\"bas-pagehead__eyebrow\">{p.eyebrow}</div> : null}\n <h1 class=\"bas-pagehead__title\">{p.title}</h1>\n {p.description ? <p class=\"bas-pagehead__desc\">{p.description}</p> : null}\n </div>\n {p.actions ? <div class=\"bas-pagehead__actions\">{p.actions}</div> : null}\n </div>\n );\n}\n\nexport interface PageTab {\n id: string;\n label: ComponentChildren;\n /** Path mode: the tab's own route. Query mode: ignored (?tab=id is used). */\n href?: string;\n}\n\n/**\n * Tabs as routes. `mode: \"query\"` puts the tab in `?tab=<id>` on the current\n * path (first tab when absent); `mode: \"path\"` gives each tab its own href.\n */\nexport function PageTabs(p: { tabs: PageTab[]; currentUrl: string; mode?: \"query\" | \"path\"; onNavigate?: Navigate }) {\n const mode = p.mode ?? \"query\";\n const url = new URL(p.currentUrl, \"http://x\");\n const activeId =\n mode === \"query\"\n ? url.searchParams.get(\"tab\") ?? p.tabs[0]?.id\n : p.tabs.find((tab) => tab.href && isActivePath(tab.href, url.pathname))?.id;\n return (\n <div class=\"bas-tabs\" role=\"tablist\" data-testid=\"page-tabs\">\n {p.tabs.map((tab) => {\n let href = tab.href ?? \"\";\n if (mode === \"query\") {\n const u = new URL(url.toString());\n u.searchParams.set(\"tab\", tab.id);\n href = u.pathname + u.search;\n }\n const active = tab.id === activeId;\n return (\n <NavLink key={tab.id} href={href} onNavigate={p.onNavigate} class={\"bas-tab\" + (active ? \" is-active\" : \"\")} data-testid={`page-tab-${tab.id}`} aria-current={active ? \"page\" : undefined}>\n {tab.label}\n </NavLink>\n );\n })}\n </div>\n );\n}\n\n// ── App shell ──────────────────────────────────────────────────────────────\n\nexport interface AppShellProps {\n brand?: ComponentChildren;\n actions?: ComponentChildren;\n groups: PreactNavGroup[];\n footer?: PreactNavItem[];\n currentPath: string;\n onNavigate?: Navigate;\n /** The notification centre's source. The bell is shown either way. */\n notifications?: NotificationSource;\n user?: ShellUser;\n userMenu?: Omit<UserMenuProps, \"user\" | \"lang\" | \"onNavigate\">;\n /** Phone behaviour: a slide-in drawer, or a 60px icon rail. */\n mobile?: \"drawer\" | \"rail\";\n /**\n * F092.6 — desktop fold: \"offcanvas\" hides the sidebar, \"icon\" keeps a 48px\n * icon rail with `brandMark` on top. Default: \"icon\" when `mobile` is \"rail\".\n */\n collapse?: \"offcanvas\" | \"icon\";\n /** The app's logo icon for the top of the icon rail. */\n brandMark?: ComponentChildren;\n /** F092.7 — the app's start page. Brand and brandMark become links to it; on a phone the click closes the drawer. */\n homeHref?: string;\n /** Accessible name for the brandMark link. Default \"Forside\"/\"Home\". */\n homeLabel?: string;\n /**\n * F092.4 — the page title in the content header, after the sidebar button.\n * Absent: the label of the active nav item (a sub-item wins over its parent).\n */\n title?: ComponentChildren;\n /** localStorage key prefix for the folded sidebar, folded groups and open items. */\n storageKey?: string;\n /** Required: the shell ships no default language (see @broberg/notifications/shell). */\n lang: Lang;\n children?: ComponentChildren;\n}\n\nexport function AppShell(p: AppShellProps) {\n const prefix = p.storageKey ?? \"broberg-app-shell\";\n const mode = p.mobile ?? \"drawer\";\n const collapse = p.collapse ?? (mode === \"rail\" ? \"icon\" : \"offcanvas\");\n const [collapsed, setCollapsed] = useState(() => readFlag(`${prefix}.collapsed`, false));\n const [drawer, setDrawer] = useState(false);\n const isMobile = useIsMobile();\n const t = TEXT[p.lang];\n const toggle = () => {\n const next = !collapsed;\n setCollapsed(next);\n writeFlag(`${prefix}.collapsed`, next);\n };\n // F092.4 — ONE sidebar button: the drawer on a phone, the fold on desktop.\n const drawerMode = isMobile && mode === \"drawer\";\n const onTrigger = () => (drawerMode ? setDrawer(!drawer) : toggle());\n const expanded = drawerMode ? drawer : !collapsed;\n const triggerLabel = drawerMode ? (drawer ? t.closeMenu : t.openMenu) : collapsed ? t.expand : t.collapse;\n const heading = p.title ?? activeNavLabel(p.groups, p.footer, p.currentPath);\n return (\n <div class=\"bas-root\" data-testid=\"app-shell\" data-mobile={mode}>\n <TopBar\n brand={p.brand}\n homeHref={p.homeHref}\n onHome={() => setDrawer(false)}\n actions={p.actions}\n notifications={p.notifications}\n user={p.user}\n userMenu={p.userMenu}\n onNavigate={p.onNavigate}\n lang={p.lang}\n />\n <div class=\"bas-row\">\n <Sidebar\n groups={p.groups}\n footer={p.footer}\n currentPath={p.currentPath}\n onNavigate={p.onNavigate}\n collapsed={collapsed}\n collapse={collapse}\n brandMark={p.brandMark}\n homeHref={p.homeHref}\n homeLabel={p.homeLabel}\n mobileOpen={drawer}\n onClose={() => setDrawer(false)}\n mobile={mode}\n header={mode === \"drawer\" ? p.brand : undefined}\n groupsKey={`${prefix}.groups`}\n itemsKey={`${prefix}.items`}\n lang={p.lang}\n />\n <main class=\"bas-main\" data-testid=\"app-content\">\n <div class=\"bas-contenthead\" data-testid=\"content-header\">\n <button\n type=\"button\"\n class=\"bas-iconbtn bas-trigger\"\n data-testid=\"sidebar-trigger\"\n aria-label={triggerLabel}\n aria-expanded={expanded}\n title={triggerLabel}\n onClick={onTrigger}\n >\n <IconPanelLeft />\n </button>\n {heading ? (\n <>\n <span class=\"bas-contenthead__sep\" data-testid=\"content-header-separator\" aria-hidden=\"true\" />\n <h1 class=\"bas-contenthead__title\" data-testid=\"content-header-title\">\n {heading}\n </h1>\n </>\n ) : null}\n </div>\n {p.children}\n </main>\n </div>\n </div>\n );\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/preact.tsx"],"names":[],"mappings":"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","file":"preact.js","sourcesContent":["// @broberg/app-shell — the framework-free core of the fleet's app shell (F092).\n//\n// The shell every app in the fleet had been copying: sidebar + top bar +\n// notification bell + user menu. cardmem and trail each had one (\"ported from\n// trail\"), and helpdesk and the appkit starter would have made the third and\n// fourth. This file holds what does not depend on a framework: the navigation\n// data model, the notification contract and its sources, and the small rules\n// both the Preact and React parts must agree on.\n//\n// Christian, 4 Oct 2026: notifications are a STANDARD part of the template, not\n// an optional slot — so the contract and a default source live here, and a new\n// app gets a working notification centre by pointing one URL at its backend.\n\n// ── Navigation ─────────────────────────────────────────────────────────────\n\n/** One sidebar entry. `icon` is whatever your framework renders (an element). */\nexport interface NavItem<Icon = unknown> {\n id: string;\n label: string;\n href: string;\n icon?: Icon;\n /** A count shown on the item (99+ above 99). 0/undefined shows nothing. */\n badge?: number;\n /**\n * Sub-items, ONE level (F092.5). An item with children is a toggle that opens\n * and closes them, not a link; its own `href` is used only to decide whether\n * it is on the current path.\n */\n children?: NavItem<Icon>[];\n}\nexport interface NavGroup<Icon = unknown> {\n label: string;\n items: NavItem<Icon>[];\n}\n\n/**\n * Is this item the current page? Exact match for \"/\", otherwise the path is the\n * item or below it (\"/board/123\" is on \"/board\", \"/boardroom\" is not).\n */\nexport function isActivePath(href: string, currentPath: string): boolean {\n const path = (currentPath.split(/[?#]/)[0] || \"/\").replace(/\\/+$/, \"\") || \"/\";\n const target = (href.split(/[?#]/)[0] || \"/\").replace(/\\/+$/, \"\") || \"/\";\n if (target === \"/\") return path === \"/\";\n return path === target || path.startsWith(target + \"/\");\n}\n\n/**\n * A notification's `navigate` is SERVER DATA, and it ends in `location.assign`.\n * `javascript:` there runs code in the app, so only a same-site path or an\n * http(s) URL is followed; anything else returns null and the row just closes.\n */\nexport function safeNavigate(target: string | null | undefined): string | null {\n if (typeof target !== \"string\") return null;\n const t = target.trim();\n if (t.startsWith(\"/\") && !t.startsWith(\"//\") && !t.startsWith(\"/\\\\\")) return t;\n try {\n const u = new URL(t);\n return u.protocol === \"https:\" || u.protocol === \"http:\" ? u.href : null;\n } catch {\n return null;\n }\n}\n\n/**\n * The label of the nav item the user is on, for the content header (F092.4).\n * Sub-items count, and the most specific match wins: on \"/models/genesis\" a\n * \"Genesis\" child beats its \"Models\" parent.\n */\nexport function activeNavLabel<Icon>(\n groups: NavGroup<Icon>[],\n footer: NavItem<Icon>[] | undefined,\n currentPath: string,\n): string | undefined {\n let best: { label: string; len: number } | undefined;\n const visit = (it: NavItem<Icon>) => {\n if (it.href && isActivePath(it.href, currentPath)) {\n const len = it.href.length;\n if (!best || len > best.len) best = { label: it.label, len };\n }\n it.children?.forEach(visit);\n };\n for (const g of groups) g.items.forEach(visit);\n footer?.forEach(visit);\n return best?.label;\n}\n\n/** \"99+\" above 99, nothing for 0 or less. */\nexport function badgeLabel(n: number | undefined): string | null {\n if (!n || n <= 0) return null;\n return n > 99 ? \"99+\" : String(n);\n}\n\n// ── Persisted UI state ─────────────────────────────────────────────────────\n\n/** Read a boolean flag from localStorage; storage errors read as `fallback`. */\nexport function readFlag(key: string, fallback: boolean): boolean {\n try {\n const v = typeof localStorage === \"undefined\" ? null : localStorage.getItem(key);\n return v === null ? fallback : v === \"1\";\n } catch {\n return fallback;\n }\n}\nexport function writeFlag(key: string, value: boolean): void {\n try {\n if (typeof localStorage !== \"undefined\") localStorage.setItem(key, value ? \"1\" : \"0\");\n } catch {\n /* private mode / quota: the UI still works, it just does not remember */\n }\n}\nexport function readSet(key: string): Set<string> {\n try {\n const raw = typeof localStorage === \"undefined\" ? null : localStorage.getItem(key);\n const v = raw ? (JSON.parse(raw) as unknown) : [];\n return new Set(Array.isArray(v) ? v.filter((x): x is string => typeof x === \"string\") : []);\n } catch {\n return new Set();\n }\n}\nexport function writeSet(key: string, value: Set<string>): void {\n try {\n if (typeof localStorage !== \"undefined\") localStorage.setItem(key, JSON.stringify([...value]));\n } catch {\n /* see writeFlag */\n }\n}\n\n// ── Avatar ─────────────────────────────────────────────────────────────────\n\n/**\n * Two initials for the avatar fallback: first letter of the first and the last\n * word, upper-cased. One word gives one letter; nothing gives \"?\".\n *\n * There is deliberately no Gravatar here (owner decision D-1dc849): the avatar\n * is the Broberg ID `picture`, and without one, initials. Gravatar would send a\n * hash of the user's email to a US service on every render.\n */\nexport function initials(name: string | undefined, email?: string): string {\n const source = (name ?? \"\").trim() || (email ?? \"\").split(\"@\")[0] || \"\";\n const words = source.split(/[\\s._-]+/).filter(Boolean);\n if (words.length === 0) return \"?\";\n const first = words[0]![0] ?? \"\";\n const last = words.length > 1 ? words[words.length - 1]![0] ?? \"\" : \"\";\n return (first + last).toUpperCase() || \"?\";\n}\n\n// ── Notifications ──────────────────────────────────────────────────────────\n//\n// REUSE, NOT A SECOND CONTRACT. The fleet already agreed the notification shape\n// in @broberg/notifications (F074): `NotificationRow` — the same field names\n// @broberg/webpush sends, end to end — and the server core that owns the ONE\n// counting rule. The shell's bell renders that row and drives its panel with\n// that package's `createBellShell`, so a server built on `createNotifications`\n// and this bell speak the same language without an adapter.\n//\n// Christian, 4 Oct 2026: notifications are a STANDARD part of the template. So\n// a source, and a default one, ship here: point one URL at your backend.\n\nimport type { NotificationRow } from \"@broberg/notifications/types\";\nexport type { NotificationRow } from \"@broberg/notifications/types\";\n\n/** Where the bell gets its data. Swap it to point at any backend. */\nexport interface NotificationSource {\n /** The rows to show (newest first). */\n loadRows(): Promise<NotificationRow[]>;\n /** THE count — your server's, which may exclude muted kinds (F074's counting rule). */\n countUnseen(): Promise<number>;\n /** Returns the ids that actually transitioned to seen. */\n markSeen(ids: readonly string[]): Promise<string[]>;\n markAllSeen(): Promise<string[]>;\n /** Called with a callback that re-counts; return an unsubscribe. Optional. */\n subscribe?(onChange: () => void): () => void;\n}\n\n/**\n * The default source: a URL on your own backend, shaped after\n * @broberg/notifications' server core so `createNotifications` sits right\n * behind it.\n *\n * GET {url} → { items: NotificationRow[], unseen: number }\n * POST {url}/seen { ids: string[] } → { clearedIds: string[], count: number }\n * POST {url}/seen-all → { clearedIds: string[], count: number }\n *\n * It re-counts when the window regains focus or the tab becomes visible, and on\n * a timer (default 60 s). A failed GET THROWS — the bell shows «could not\n * load», never an empty list: \"could not fetch\" and \"nothing new\" must not look\n * the same.\n */\nexport function createFetchNotificationSource(opts: {\n url: string;\n fetch?: typeof fetch;\n /** Re-count interval in ms. 0 turns it off. Default 60 000. */\n pollMs?: number;\n credentials?: RequestCredentials;\n}): NotificationSource {\n const base = opts.url.replace(/\\/+$/, \"\");\n const doFetch = (input: string, init?: RequestInit) =>\n (opts.fetch ?? fetch)(input, { credentials: opts.credentials ?? \"include\", ...init });\n const get = async (): Promise<{ items: NotificationRow[]; unseen: number }> => {\n const res = await doFetch(base, { headers: { accept: \"application/json\" } });\n if (!res.ok) throw new Error(`HTTP ${res.status}`);\n const body = (await res.json().catch(() => null)) as { items?: unknown; unseen?: unknown } | null;\n if (!body || !Array.isArray(body.items)) throw new Error(\"response has no items array\");\n const items = body.items as NotificationRow[];\n const unseen = typeof body.unseen === \"number\" ? body.unseen : items.filter((n) => n.seenAt == null).length;\n return { items, unseen };\n };\n const post = async (path: string, body?: unknown): Promise<string[]> => {\n const res = await doFetch(`${base}${path}`, {\n method: \"POST\",\n headers: body === undefined ? undefined : { \"content-type\": \"application/json\" },\n body: body === undefined ? undefined : JSON.stringify(body),\n });\n if (!res.ok) throw new Error(`HTTP ${res.status}`);\n const r = (await res.json().catch(() => ({}))) as { clearedIds?: unknown };\n return Array.isArray(r.clearedIds) ? (r.clearedIds as string[]) : [];\n };\n return {\n loadRows: async () => (await get()).items,\n countUnseen: async () => (await get()).unseen,\n markSeen: (ids) => post(\"/seen\", { ids }),\n markAllSeen: () => post(\"/seen-all\"),\n subscribe(onChange) {\n if (typeof window === \"undefined\") return () => {};\n const onVisible = () => {\n if (document.visibilityState === \"visible\") onChange();\n };\n window.addEventListener(\"focus\", onChange);\n document.addEventListener(\"visibilitychange\", onVisible);\n const ms = opts.pollMs ?? 60_000;\n const timer = ms > 0 ? setInterval(onChange, ms) : null;\n return () => {\n window.removeEventListener(\"focus\", onChange);\n document.removeEventListener(\"visibilitychange\", onVisible);\n if (timer) clearInterval(timer);\n };\n },\n };\n}\n\n/** An in-memory source for demos and tests. */\nexport function createMemoryNotificationSource(initial: NotificationRow[] = []): NotificationSource & {\n push(n: NotificationRow): void;\n rows(): NotificationRow[];\n} {\n let rows = initial.map((n) => ({ ...n }));\n const listeners = new Set<() => void>();\n const emit = () => listeners.forEach((l) => l());\n const mark = (pred: (n: NotificationRow) => boolean): string[] => {\n const now = Date.now();\n const cleared: string[] = [];\n rows = rows.map((n) => {\n if (n.seenAt == null && pred(n)) {\n cleared.push(n.id);\n return { ...n, seenAt: now };\n }\n return n;\n });\n if (cleared.length) emit();\n return cleared;\n };\n return {\n loadRows: async () => rows.map((n) => ({ ...n })),\n countUnseen: async () => rows.filter((n) => n.seenAt == null).length,\n markSeen: async (ids) => mark((n) => ids.includes(n.id)),\n markAllSeen: async () => mark(() => true),\n subscribe(onChange) {\n listeners.add(onChange);\n return () => listeners.delete(onChange);\n },\n push(n) {\n rows = [n, ...rows];\n emit();\n },\n rows: () => rows.map((n) => ({ ...n })),\n };\n}\n\n/** \"nu\", \"5 min\", \"3 t\", \"i går\", \"4 d\" (da) or the English equivalents. */\nexport function relativeTime(ts: string | number, lang: \"da\" | \"en\", now = Date.now()): string {\n const ms = typeof ts === \"number\" ? ts : Date.parse(ts);\n if (!Number.isFinite(ms)) return \"\";\n const m = Math.floor((now - ms) / 60_000);\n if (m < 1) return lang === \"da\" ? \"nu\" : \"now\";\n if (m < 60) return `${m} min`;\n const h = Math.floor(m / 60);\n if (h < 24) return lang === \"da\" ? `${h} t` : `${h} h`;\n const d = Math.floor(h / 24);\n if (d === 1) return lang === \"da\" ? \"i går\" : \"yesterday\";\n return `${d} d`;\n}\n\n// ── Text ───────────────────────────────────────────────────────────────────\n\nexport const TEXT = {\n da: {\n openMenu: \"Åbn menu\",\n closeMenu: \"Luk menu\",\n home: \"Forside\",\n collapse: \"Skjul sidemenu\",\n expand: \"Vis sidemenu\",\n notifications: \"Notifikationer\",\n markAllRead: \"Markér alle læst\",\n noNotifications: \"Ingen notifikationer endnu.\",\n couldNotLoad: \"Kunne ikke hente notifikationer.\",\n seeAll: \"Vis alle\",\n close: \"Luk\",\n account: \"Konto\",\n signOut: \"Log ud\",\n theme: \"Tema\",\n light: \"Lys\",\n dark: \"Mørk\",\n system: \"System\",\n palette: \"Palet\",\n surfaces: \"Flader\",\n flat: \"Flade\",\n layered: \"Lag\",\n backdrop: \"Baggrund\",\n neurons: \"Neuroner\",\n plain: \"Ren\",\n },\n en: {\n openMenu: \"Open menu\",\n closeMenu: \"Close menu\",\n home: \"Home\",\n collapse: \"Hide sidebar\",\n expand: \"Show sidebar\",\n notifications: \"Notifications\",\n markAllRead: \"Mark all read\",\n noNotifications: \"No notifications yet.\",\n couldNotLoad: \"Could not load notifications.\",\n seeAll: \"See all\",\n close: \"Close\",\n account: \"Account\",\n signOut: \"Sign out\",\n theme: \"Theme\",\n light: \"Light\",\n dark: \"Dark\",\n system: \"System\",\n palette: \"Palette\",\n surfaces: \"Surfaces\",\n flat: \"Flat\",\n layered: \"Layered\",\n backdrop: \"Backdrop\",\n neurons: \"Neurons\",\n plain: \"Plain\",\n },\n} as const;\nexport type Lang = keyof typeof TEXT;\n","/** @jsxImportSource preact */\n// @broberg/app-shell/preact — the fleet's app shell for Stack B (F092).\n//\n// Lifted in shape from cardmem (apps/web/src/components/ui: top-nav, app-sidebar,\n// notification-bell, user-menu, page-header, page-tabs; origin/main af80f192)\n// and trail (the original), rewritten as props-in components: nothing here\n// knows about any app's auth, router or data. Styling is css/app-shell.css,\n// on @broberg/theme's tokens, so every palette × light/dark × flat/layered works.\n//\n// Use the whole thing:\n// <AppShell brand={…} groups={…} currentPath={path} user={…} notifications={source}\n// accountHref=\"https://id.broberg.ai/account\" onSignOut={…}>{page}</AppShell>\n// or compose the parts (Sidebar, TopBar, NotificationBell, UserMenu,\n// PageHeader, PageTabs) in your own layout.\n\nimport type { ComponentChildren, JSX } from \"preact\";\nimport { useEffect, useMemo, useRef, useState } from \"preact/hooks\";\nimport { createBellShell } from \"@broberg/notifications/shell\";\nimport {\n getBackdrop,\n getPalette,\n getPreference,\n getSurfaces,\n onBackdropChange,\n onPaletteChange,\n onSurfacesChange,\n onThemeChange,\n PALETTE_LABELS,\n PALETTES,\n setBackdrop,\n setPalette,\n setPreference,\n setSurfaces,\n type Backdrop,\n type Palette,\n type Surfaces,\n type ThemePreference,\n} from \"@broberg/theme\";\nimport {\n activeNavLabel,\n badgeLabel,\n initials,\n isActivePath,\n readFlag,\n readSet,\n relativeTime,\n safeNavigate,\n TEXT,\n writeFlag,\n writeSet,\n type Lang,\n type NavGroup,\n type NavItem,\n type NotificationRow,\n type NotificationSource,\n} from \"./index\";\n\nexport * from \"./index\";\n\ntype Icon = ComponentChildren;\nexport type PreactNavItem = NavItem<Icon>;\nexport type PreactNavGroup = NavGroup<Icon>;\n/** Called instead of a full page load when given. Return false to let the browser navigate. */\nexport type Navigate = (href: string) => void;\n\nconst MOBILE_QUERY = \"(max-width: 767px)\";\n\n/** True below 768px. Follows the window as it resizes. */\nexport function useIsMobile(): boolean {\n const get = () => typeof window !== \"undefined\" && typeof window.matchMedia === \"function\" && window.matchMedia(MOBILE_QUERY).matches;\n const [mobile, setMobile] = useState(get);\n useEffect(() => {\n if (typeof window === \"undefined\" || typeof window.matchMedia !== \"function\") return;\n const mq = window.matchMedia(MOBILE_QUERY);\n const on = () => setMobile(mq.matches);\n mq.addEventListener?.(\"change\", on);\n return () => mq.removeEventListener?.(\"change\", on);\n }, []);\n return mobile;\n}\n\n/** An <a> that hands the click to `onNavigate` (SPA) when given, else a normal link. */\nfunction NavLink(props: {\n href: string;\n onNavigate?: Navigate;\n onAfter?: () => void;\n class?: string;\n children: ComponentChildren;\n \"data-testid\"?: string;\n \"aria-current\"?: \"page\";\n title?: string;\n}) {\n const { href, onNavigate, onAfter, children, ...rest } = props;\n return (\n <a\n {...rest}\n href={href}\n onClick={(e: JSX.TargetedMouseEvent<HTMLAnchorElement>) => {\n if (onNavigate && !e.metaKey && !e.ctrlKey && !e.shiftKey && e.button === 0) {\n e.preventDefault();\n onNavigate(href);\n }\n onAfter?.();\n }}\n >\n {children}\n </a>\n );\n}\n\n// ── Icons (inline, so the package has no icon dependency) ─────────────────\nconst svg = (d: ComponentChildren, size = 18) => (\n <svg viewBox=\"0 0 24 24\" width={size} height={size} fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.9\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\">\n {d}\n </svg>\n);\nconst IconMenu = () => svg(<path d=\"M4 6h16M4 12h16M4 18h16\" />, 20);\nconst IconChevron = ({ open }: { open?: boolean }) => (\n <span class={\"bas-chev\" + (open ? \" is-open\" : \"\")}>{svg(<path d=\"m9 18 6-6-6-6\" />, 12)}</span>\n);\n// lucide \"panel-left\" (ISC), the exact icon in shadcn's SidebarTrigger (F092.4).\nconst IconPanelLeft = () => svg(<><rect width=\"18\" height=\"18\" x=\"3\" y=\"3\" rx=\"2\" /><path d=\"M9 3v18\" /></>, 16);\nconst IconBell = () => svg(<><path d=\"M6 8a6 6 0 0 1 12 0c0 7 3 9 3 9H3s3-2 3-9\" /><path d=\"M10.3 21a1.94 1.94 0 0 0 3.4 0\" /></>, 19);\nconst IconLogOut = () => svg(<><path d=\"M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4\" /><path d=\"m16 17 5-5-5-5\" /><path d=\"M21 12H9\" /></>, 14);\nconst IconUser = () => svg(<><circle cx=\"12\" cy=\"8\" r=\"4\" /><path d=\"M4 21a8 8 0 0 1 16 0\" /></>, 14);\n\n// ── Sidebar ────────────────────────────────────────────────────────────────\n\nexport interface SidebarProps {\n groups: PreactNavGroup[];\n footer?: PreactNavItem[];\n currentPath: string;\n onNavigate?: Navigate;\n /** Desktop: is the sidebar folded (to nothing, or to the icon rail — see `collapse`). */\n collapsed?: boolean;\n /**\n * F092.6 — what \"folded\" means on desktop, as shadcn's `collapsible`:\n * \"offcanvas\" hides the sidebar, \"icon\" keeps a 48px rail of item icons with\n * `brandMark` on top. Default: \"icon\" when `mobile` is \"rail\", else \"offcanvas\".\n */\n collapse?: \"offcanvas\" | \"icon\";\n /** The app's logo icon, shown at the top of the icon rail. */\n brandMark?: ComponentChildren;\n /** F092.7 — the app's start page: `header` and `brandMark` become links to it. */\n homeHref?: string;\n /** Accessible name of the brandMark link (it has no visible text). Default \"Forside\"/\"Home\". */\n homeLabel?: string;\n /** Phone, drawer mode: is the drawer open. */\n mobileOpen?: boolean;\n onClose?: () => void;\n mobile?: \"drawer\" | \"rail\";\n /** Shown at the top of the sidebar (e.g. the brand on a phone). */\n header?: ComponentChildren;\n /** localStorage key for which groups are folded. */\n groupsKey?: string;\n /** localStorage key for which items with children are open (F092.5). */\n itemsKey?: string;\n lang: Lang;\n}\n\nexport function Sidebar(p: SidebarProps) {\n const key = p.groupsKey ?? \"broberg-app-shell.groups\";\n const itemsKey = p.itemsKey ?? \"broberg-app-shell.items\";\n const mode = p.mobile ?? \"drawer\";\n const collapseMode = p.collapse ?? (mode === \"rail\" ? \"icon\" : \"offcanvas\");\n const isMobile = useIsMobile();\n // The rail: on a phone in rail mode, or on desktop when folded to icons.\n const railed = isMobile ? mode === \"rail\" : !!p.collapsed && collapseMode === \"icon\";\n\n const [folded, setFolded] = useState<Set<string>>(() => readSet(key));\n const toggleGroup = (label: string) => {\n const next = new Set(folded);\n next.has(label) ? next.delete(label) : next.add(label);\n setFolded(next);\n writeSet(key, next);\n };\n\n const all = [...p.groups.flatMap((g) => g.items), ...(p.footer ?? [])];\n const childActive = (it: PreactNavItem) => !!it.children?.some((c) => isActivePath(c.href, p.currentPath));\n // Open = what the user left open, plus any parent of the page they are on.\n const [openItems, setOpenItems] = useState<Set<string>>(() => {\n const s = readSet(itemsKey);\n for (const it of all) if (childActive(it)) s.add(it.id);\n return s;\n });\n const toggleItem = (id: string) => {\n const next = new Set(openItems);\n next.has(id) ? next.delete(id) : next.add(id);\n setOpenItems(next);\n writeSet(itemsKey, next);\n };\n\n // F092.6 — the rail's flyout for an item with children.\n const [flyout, setFlyout] = useState<{ id: string; top: number; left: number } | null>(null);\n const flyoutRef = useRef<HTMLDivElement>(null);\n useEffect(() => {\n if (!flyout) return;\n const onKey = (e: KeyboardEvent) => {\n if (e.key === \"Escape\") setFlyout(null);\n };\n const onDown = (e: MouseEvent) => {\n const t = e.target as Node | null;\n if (flyoutRef.current && t && flyoutRef.current.contains(t)) return;\n if (t instanceof Element && t.closest(`[data-flyout-for=\"${flyout.id}\"]`)) return;\n setFlyout(null);\n };\n document.addEventListener(\"keydown\", onKey);\n document.addEventListener(\"mousedown\", onDown);\n return () => {\n document.removeEventListener(\"keydown\", onKey);\n document.removeEventListener(\"mousedown\", onDown);\n };\n }, [flyout]);\n useEffect(() => {\n if (!railed) setFlyout(null);\n }, [railed]);\n\n const close = () => {\n setFlyout(null);\n p.onClose?.();\n };\n\n const leaf = (it: PreactNavItem, sub = false) => {\n const active = isActivePath(it.href, p.currentPath);\n const badge = badgeLabel(it.badge);\n return (\n <NavLink\n key={it.id}\n href={it.href}\n onNavigate={p.onNavigate}\n onAfter={close}\n class={\"bas-item\" + (sub ? \" bas-item--sub\" : \"\") + (active ? \" is-active\" : \"\")}\n data-testid={`sidebar-item-${it.id}`}\n aria-current={active ? \"page\" : undefined}\n aria-label={railed && !sub ? it.label : undefined}\n title={it.label}\n >\n {active && !sub ? <span class=\"bas-item__bar\" /> : null}\n {it.icon ? <span class=\"bas-item__icon\">{it.icon}</span> : null}\n <span class=\"bas-item__label\">{it.label}</span>\n {badge ? <span class=\"bas-item__count\" data-testid={`sidebar-badge-${it.id}`}>{badge}</span> : null}\n </NavLink>\n );\n };\n\n const parent = (it: PreactNavItem) => {\n const children = it.children!;\n const onPage = childActive(it) || isActivePath(it.href, p.currentPath);\n const open = railed ? flyout?.id === it.id : openItems.has(it.id);\n const onClick = (e: JSX.TargetedMouseEvent<HTMLButtonElement>) => {\n if (!railed) return toggleItem(it.id);\n if (flyout?.id === it.id) return setFlyout(null);\n const r = e.currentTarget.getBoundingClientRect();\n setFlyout({ id: it.id, top: r.top, left: r.right + 6 });\n };\n return (\n <div class=\"bas-itemgroup\" key={it.id}>\n <button\n type=\"button\"\n class={\"bas-item bas-item--parent\" + (onPage ? \" is-parent-active\" : \"\")}\n data-testid={`sidebar-item-${it.id}-toggle`}\n data-flyout-for={it.id}\n aria-expanded={open}\n aria-label={railed ? it.label : undefined}\n title={it.label}\n onClick={onClick}\n >\n {onPage && railed ? <span class=\"bas-item__bar\" /> : null}\n {it.icon ? <span class=\"bas-item__icon\">{it.icon}</span> : null}\n <span class=\"bas-item__label\">{it.label}</span>\n <span class=\"bas-item__chev\">\n <IconChevron open={open} />\n </span>\n </button>\n {!railed && open ? <div class=\"bas-sub\">{children.map((c) => leaf(c, true))}</div> : null}\n {railed && flyout?.id === it.id ? (\n <div\n ref={flyoutRef}\n class=\"bas-flyout\"\n data-testid={`sidebar-flyout-${it.id}`}\n role=\"menu\"\n aria-label={it.label}\n style={{ top: `${flyout.top}px`, left: `${flyout.left}px` }}\n >\n <div class=\"bas-flyout__title\">{it.label}</div>\n {children.map((c) => leaf(c, true))}\n </div>\n ) : null}\n </div>\n );\n };\n\n const item = (it: PreactNavItem) => (it.children?.length ? parent(it) : leaf(it));\n\n return (\n <>\n {mode === \"drawer\" ? (\n <div class={\"bas-backdrop\" + (p.mobileOpen ? \" is-open\" : \"\")} data-testid=\"sidebar-backdrop\" onClick={close} />\n ) : null}\n <aside\n class={\n \"bas-sidebar\" +\n ` is-mobile-${mode}` +\n (p.mobileOpen ? \" is-open\" : \"\") +\n (p.collapsed ? \" is-collapsed\" : \"\") +\n (railed ? \" is-railed\" : \"\")\n }\n data-testid=\"sidebar-root\"\n data-mobile={mode}\n data-collapse={collapseMode}\n aria-label=\"Navigation\"\n >\n {p.header || p.brandMark ? (\n <div class=\"bas-sidebar__head\">\n {p.header ? (\n <div class=\"bas-sidebar__brand\">\n {p.homeHref ? (\n <NavLink href={p.homeHref} onNavigate={p.onNavigate} onAfter={close} class=\"bas-home\" data-testid=\"sidebar-brand-home\">\n {p.header}\n </NavLink>\n ) : (\n p.header\n )}\n </div>\n ) : null}\n {p.brandMark ? (\n <div class=\"bas-sidebar__mark\" data-testid=\"sidebar-brand-mark\">\n {p.homeHref ? (\n <NavLink\n href={p.homeHref}\n onNavigate={p.onNavigate}\n onAfter={close}\n class=\"bas-home\"\n data-testid=\"brand-mark-home\"\n aria-label={p.homeLabel ?? TEXT[p.lang].home}\n title={p.homeLabel ?? TEXT[p.lang].home}\n >\n {p.brandMark}\n </NavLink>\n ) : (\n p.brandMark\n )}\n </div>\n ) : null}\n </div>\n ) : null}\n <nav class=\"bas-sidebar__nav\">\n {p.groups.map((g) => {\n const open = railed || !folded.has(g.label);\n const slug = g.label.toLowerCase().replace(/[^a-z0-9]+/g, \"-\");\n return (\n <div class=\"bas-group\" key={g.label}>\n <button type=\"button\" class=\"bas-group__label\" data-testid={`sidebar-group-${slug}`} aria-expanded={open} onClick={() => toggleGroup(g.label)}>\n <IconChevron open={open} />\n <span>{g.label}</span>\n </button>\n {open ? g.items.map(item) : null}\n </div>\n );\n })}\n </nav>\n {p.footer?.length ? <div class=\"bas-sidebar__foot\">{p.footer.map(item)}</div> : null}\n </aside>\n </>\n );\n}\n\n// ── Notification bell ──────────────────────────────────────────────────────\n//\n// Driven by @broberg/notifications' createBellShell: one count however many\n// bells, Escape acts on the innermost layer, and the ids \"mark all read\"\n// actually cleared are held for the visit. This component is only the DOM.\n\nexport interface NotificationBellProps {\n /** Where the data comes from. Absent: the bell is still there, with an empty list. */\n source?: NotificationSource;\n onNavigate?: Navigate;\n /** Required on purpose: a default would make \"nobody chose\" look like a choice. */\n lang: Lang;\n}\n\nexport function NotificationBell({ source, onNavigate, lang }: NotificationBellProps) {\n const t = TEXT[lang];\n const mobile = useIsMobile();\n const [error, setError] = useState<string | null>(null);\n const lastCount = useRef(0);\n const shell = useMemo(\n () =>\n createBellShell({\n labels: { bell: t.notifications, panel: t.notifications, markAll: t.markAllRead, seeAll: t.seeAll, empty: t.noNotifications, close: t.close },\n countUnseen: async () => {\n if (!source) return 0;\n try {\n lastCount.current = await source.countUnseen();\n setError(null);\n } catch (e) {\n setError(e instanceof Error ? e.message : String(e));\n }\n return lastCount.current;\n },\n loadRows: async () => {\n if (!source) return [];\n try {\n return await source.loadRows();\n } catch (e) {\n setError(e instanceof Error ? e.message : String(e));\n return [];\n }\n },\n markAllSeen: async () => (source ? source.markAllSeen() : []),\n }),\n [source, lang],\n );\n const [state, setState] = useState(shell.getState());\n useEffect(() => shell.subscribe(setState), [shell]);\n useEffect(() => {\n setState(shell.getState());\n void shell.refresh();\n return source?.subscribe?.(() => {\n if (shell.getState().open) void shell.open(shell.getState().anchor);\n else void shell.refresh();\n });\n }, [shell, source]);\n useEffect(() => {\n if (!state.open) return;\n const onKey = (e: KeyboardEvent) => {\n if (e.key === \"Escape\" && shell.escape() === \"close\") e.preventDefault();\n };\n document.addEventListener(\"keydown\", onKey);\n return () => document.removeEventListener(\"keydown\", onKey);\n }, [state.open, shell]);\n\n const label = badgeLabel(state.count);\n const onRow = async (n: NotificationRow) => {\n shell.close();\n if (n.seenAt == null && source) {\n await source.markSeen([n.id]);\n await shell.refresh();\n }\n const target = safeNavigate(n.navigate);\n if (target) {\n if (onNavigate) onNavigate(target);\n else if (typeof window !== \"undefined\") window.location.assign(target);\n }\n };\n const seen = (n: NotificationRow) => n.seenAt != null || state.clearedIds.includes(n.id);\n\n return (\n <div class=\"bas-bell\">\n <button\n type=\"button\"\n class=\"bas-iconbtn\"\n data-testid=\"topbar-notifications\"\n aria-label={t.notifications}\n aria-expanded={state.open}\n onClick={(e: JSX.TargetedMouseEvent<HTMLButtonElement>) => {\n const r = e.currentTarget.getBoundingClientRect();\n void shell.toggle({ top: r.top, right: r.right, bottom: r.bottom, left: r.left, width: r.width, height: r.height } as never);\n }}\n >\n <IconBell />\n {label ? (\n <span class=\"bas-bell__count\" data-testid=\"topbar-notifications-count\">\n {label}\n </span>\n ) : null}\n </button>\n {state.open ? (\n <>\n <div class={\"bas-overlay\" + (mobile ? \" is-dim\" : \"\")} data-testid=\"notifications-backdrop\" onClick={() => shell.close()} />\n <div\n class={\"bas-panel \" + (mobile ? \"bas-panel--sheet\" : \"bas-panel--drop\")}\n role=\"dialog\"\n aria-label={shell.labels.panel}\n data-testid={mobile ? \"notifications-drawer\" : \"notifications-dropdown\"}\n >\n <div class=\"bas-panel__head\">\n <h3>{t.notifications}</h3>\n <button type=\"button\" class=\"bas-link\" data-testid=\"notifications-mark-all\" onClick={() => void shell.markAllSeen()} disabled={!state.count}>\n {shell.labels.markAll}\n </button>\n </div>\n <div class=\"bas-panel__list\" data-testid=\"notifications-list\">\n {error && state.rows.length === 0 ? (\n <p class=\"bas-panel__note is-error\" data-testid=\"notifications-error\">\n {t.couldNotLoad}\n </p>\n ) : state.rows.length === 0 ? (\n <p class=\"bas-panel__note\" data-testid=\"notifications-empty\">\n {shell.labels.empty}\n </p>\n ) : (\n state.rows.map((n) => (\n <button\n type=\"button\"\n key={n.id}\n class={\"bas-note\" + (seen(n) ? \" is-read\" : \"\")}\n data-testid=\"notification-row\"\n data-id={n.id}\n onClick={() => void onRow(n)}\n >\n <span class=\"bas-note__text\">\n <span class=\"bas-note__title\">{n.title}</span>\n {n.body ? <span class=\"bas-note__body\">{n.body}</span> : null}\n <span class=\"bas-note__time\">{relativeTime(n.createdAt, lang)}</span>\n </span>\n {!seen(n) ? <span class=\"bas-note__dot\" /> : null}\n </button>\n ))\n )}\n </div>\n </div>\n </>\n ) : null}\n </div>\n );\n}\n\n// ── User menu ──────────────────────────────────────────────────────────────\n\nexport interface ShellUser {\n name?: string;\n email?: string;\n /** Broberg ID OIDC `picture`. Without it: initials. Never Gravatar (D-1dc849). */\n picture?: string;\n}\nexport interface UserMenuItem {\n id: string;\n label: string;\n icon?: Icon;\n href?: string;\n onSelect?: () => void;\n}\nexport interface UserMenuProps {\n user: ShellUser;\n /** «Konto» → Broberg ID's account page. */\n accountHref?: string;\n items?: UserMenuItem[];\n onSignOut?: () => void | Promise<void>;\n onNavigate?: Navigate;\n /** Show Theme · Palette · Surfaces · Backdrop. Default true. */\n appearance?: boolean;\n lang: Lang;\n}\n\nexport function Avatar({ user, size = 28 }: { user: ShellUser; size?: number }) {\n const [broken, setBroken] = useState(false);\n const style = `width:${size}px;height:${size}px;font-size:${Math.round(size * 0.4)}px`;\n if (user.picture && !broken) {\n return <img class=\"bas-avatar\" style={style} src={user.picture} alt=\"\" referrerpolicy=\"no-referrer\" onError={() => setBroken(true)} data-testid=\"avatar-picture\" />;\n }\n return (\n <span class=\"bas-avatar bas-avatar--initials\" style={style} data-testid=\"avatar-initials\" aria-hidden=\"true\">\n {initials(user.name, user.email)}\n </span>\n );\n}\n\nfunction Segmented<T extends string>(props: { testid: string; value: T; options: readonly (readonly [T, string])[]; onChange: (v: T) => void }) {\n return (\n <div class=\"bas-seg\" data-testid={props.testid} role=\"group\">\n {props.options.map(([v, label]) => (\n <button type=\"button\" key={v} aria-pressed={props.value === v} data-testid={`${props.testid}-${v}`} onClick={() => props.onChange(v)}>\n {label}\n </button>\n ))}\n </div>\n );\n}\n\nexport function UserMenu(p: UserMenuProps) {\n const t = TEXT[p.lang];\n const [open, setOpen] = useState(false);\n const [busy, setBusy] = useState(false);\n const root = useRef<HTMLDivElement>(null);\n const [pref, setPref] = useState<ThemePreference>(() => getPreference());\n const [palette, setPal] = useState<Palette>(() => getPalette());\n const [surfaces, setSurf] = useState<Surfaces>(() => getSurfaces());\n const [backdrop, setBack] = useState<Backdrop>(() => getBackdrop());\n\n useEffect(() => {\n const offs = [\n onThemeChange(() => setPref(getPreference())),\n onPaletteChange(setPal),\n onSurfacesChange(setSurf),\n onBackdropChange(setBack),\n ];\n return () => offs.forEach((off) => off());\n }, []);\n\n useEffect(() => {\n if (!open) return;\n const onDown = (e: MouseEvent) => {\n if (root.current && !root.current.contains(e.target as Node)) setOpen(false);\n };\n const onKey = (e: KeyboardEvent) => e.key === \"Escape\" && setOpen(false);\n document.addEventListener(\"mousedown\", onDown);\n document.addEventListener(\"keydown\", onKey);\n return () => {\n document.removeEventListener(\"mousedown\", onDown);\n document.removeEventListener(\"keydown\", onKey);\n };\n }, [open]);\n\n const firstName = (p.user.name ?? \"\").trim().split(/\\s+/)[0] || p.user.email || \"\";\n const signOut = async () => {\n setBusy(true);\n try {\n await p.onSignOut?.();\n } finally {\n setBusy(false);\n setOpen(false);\n }\n };\n\n return (\n <div class=\"bas-usermenu\" ref={root}>\n <button\n type=\"button\"\n class={\"bas-userbtn\" + (open ? \" is-open\" : \"\")}\n data-testid=\"topbar-user-menu\"\n aria-haspopup=\"menu\"\n aria-expanded={open}\n aria-label={p.user.email ?? p.user.name ?? t.account}\n onClick={() => setOpen((v) => !v)}\n >\n <Avatar user={p.user} />\n <span class=\"bas-userbtn__name\">{firstName}</span>\n </button>\n {open ? (\n <div class=\"bas-menu\" role=\"menu\" data-testid=\"topbar-user-menu-dropdown\">\n <div class=\"bas-menu__who\">\n <Avatar user={p.user} size={36} />\n <div class=\"bas-menu__whotext\">\n {p.user.name ? <div class=\"bas-menu__name\">{p.user.name}</div> : null}\n {p.user.email ? <div class=\"bas-menu__email\">{p.user.email}</div> : null}\n </div>\n </div>\n <div class=\"bas-sep\" />\n {p.accountHref ? (\n <a class=\"bas-mi\" href={p.accountHref} data-testid=\"user-menu-account\" role=\"menuitem\">\n <IconUser />\n <span>{t.account}</span>\n </a>\n ) : null}\n {(p.items ?? []).map((it) =>\n it.href ? (\n <NavLink key={it.id} href={it.href} onNavigate={p.onNavigate} onAfter={() => setOpen(false)} class=\"bas-mi\" data-testid={`user-menu-${it.id}`}>\n {it.icon ?? null}\n <span>{it.label}</span>\n </NavLink>\n ) : (\n <button\n key={it.id}\n type=\"button\"\n class=\"bas-mi\"\n role=\"menuitem\"\n data-testid={`user-menu-${it.id}`}\n onClick={() => {\n setOpen(false);\n it.onSelect?.();\n }}\n >\n {it.icon ?? null}\n <span>{it.label}</span>\n </button>\n ),\n )}\n {p.appearance !== false ? (\n <>\n <div class=\"bas-sep\" />\n <div class=\"bas-prefs\">\n <div class=\"bas-pref\">\n <span>{t.theme}</span>\n <Segmented\n testid=\"user-menu-theme\"\n value={pref as \"light\" | \"dark\" | \"system\"}\n options={[[\"light\", t.light], [\"dark\", t.dark], [\"system\", t.system]] as const}\n onChange={(v) => {\n setPreference(v);\n setPref(v);\n }}\n />\n </div>\n <div class=\"bas-pref\">\n <span>{t.palette}</span>\n <Segmented testid=\"user-menu-palette\" value={palette} options={PALETTES.map((x) => [x, PALETTE_LABELS[x]] as const)} onChange={setPalette} />\n </div>\n <div class=\"bas-pref\">\n <span>{t.surfaces}</span>\n <Segmented testid=\"user-menu-surfaces\" value={surfaces} options={[[\"flat\", t.flat], [\"layered\", t.layered]] as const} onChange={setSurfaces} />\n </div>\n <div class=\"bas-pref\">\n <span>{t.backdrop}</span>\n <Segmented testid=\"user-menu-backdrop\" value={backdrop} options={[[\"neurons\", t.neurons], [\"plain\", t.plain]] as const} onChange={setBackdrop} />\n </div>\n </div>\n </>\n ) : null}\n {p.onSignOut ? (\n <>\n <div class=\"bas-sep\" />\n <button type=\"button\" class=\"bas-mi is-danger\" role=\"menuitem\" data-testid=\"topbar-sign-out\" disabled={busy} onClick={() => void signOut()}>\n <IconLogOut />\n <span>{t.signOut}</span>\n </button>\n </>\n ) : null}\n </div>\n ) : null}\n </div>\n );\n}\n\n// ── Top bar ────────────────────────────────────────────────────────────────\n\nexport interface TopBarProps {\n /** F092.7 — when set, the brand is a link to the app's start page. */\n homeHref?: string;\n /** Called after the brand link was followed (AppShell closes the drawer). */\n onHome?: () => void;\n brand?: ComponentChildren;\n /** Anything app-specific (project switcher, search) between brand and bell. */\n actions?: ComponentChildren;\n /** Drawer mode on a phone: show the hamburger and call this. */\n onOpenMenu?: () => void;\n notifications?: NotificationSource;\n user?: ShellUser;\n userMenu?: Omit<UserMenuProps, \"user\" | \"lang\" | \"onNavigate\">;\n onNavigate?: Navigate;\n lang: Lang;\n}\n\n/** Brand left, actions, then the notification bell and the user menu ALWAYS last, in that order. */\nexport function TopBar(p: TopBarProps) {\n const t = TEXT[p.lang];\n return (\n <header class=\"bas-topbar\" data-testid=\"topbar-root\">\n <div class=\"bas-topbar__inner\">\n {p.onOpenMenu ? (\n <button type=\"button\" class=\"bas-iconbtn bas-hamburger\" data-testid=\"sidebar-toggle\" aria-label={t.openMenu} onClick={p.onOpenMenu}>\n <IconMenu />\n </button>\n ) : null}\n {p.brand ? (\n <div class=\"bas-topbar__brand\">\n {p.homeHref ? (\n <NavLink href={p.homeHref} onNavigate={p.onNavigate} onAfter={p.onHome} class=\"bas-home\" data-testid=\"brand-home\">\n {p.brand}\n </NavLink>\n ) : (\n p.brand\n )}\n </div>\n ) : null}\n {p.actions ? <div class=\"bas-topbar__actions\">{p.actions}</div> : null}\n <div class=\"bas-spacer\" />\n <NotificationBell source={p.notifications} onNavigate={p.onNavigate} lang={p.lang} />\n {p.user ? <UserMenu user={p.user} {...p.userMenu} onNavigate={p.onNavigate} lang={p.lang} /> : null}\n </div>\n </header>\n );\n}\n\n// ── Page header + tabs ─────────────────────────────────────────────────────\n\n/**\n * Optional `title` (0.2.1): inside AppShell the page title already sits in the\n * content header, so a page can use PageHeader for its description and actions\n * alone — no second, and no empty, <h1>.\n */\nexport function PageHeader(p: { eyebrow?: ComponentChildren; title?: ComponentChildren; description?: ComponentChildren; actions?: ComponentChildren }) {\n return (\n <div class=\"bas-pagehead\" data-testid=\"page-header\">\n <div class=\"bas-pagehead__text\">\n {p.eyebrow ? <div class=\"bas-pagehead__eyebrow\">{p.eyebrow}</div> : null}\n {p.title != null && p.title !== \"\" ? <h1 class=\"bas-pagehead__title\">{p.title}</h1> : null}\n {p.description ? <p class=\"bas-pagehead__desc\">{p.description}</p> : null}\n </div>\n {p.actions ? <div class=\"bas-pagehead__actions\">{p.actions}</div> : null}\n </div>\n );\n}\n\nexport interface PageTab {\n id: string;\n label: ComponentChildren;\n /** Path mode: the tab's own route. Query mode: ignored (?tab=id is used). */\n href?: string;\n}\n\n/**\n * Tabs as routes. `mode: \"query\"` puts the tab in `?tab=<id>` on the current\n * path (first tab when absent); `mode: \"path\"` gives each tab its own href.\n */\nexport function PageTabs(p: { tabs: PageTab[]; currentUrl: string; mode?: \"query\" | \"path\"; onNavigate?: Navigate }) {\n const mode = p.mode ?? \"query\";\n const url = new URL(p.currentUrl, \"http://x\");\n const activeId =\n mode === \"query\"\n ? url.searchParams.get(\"tab\") ?? p.tabs[0]?.id\n : p.tabs.find((tab) => tab.href && isActivePath(tab.href, url.pathname))?.id;\n return (\n <div class=\"bas-tabs\" role=\"tablist\" data-testid=\"page-tabs\">\n {p.tabs.map((tab) => {\n let href = tab.href ?? \"\";\n if (mode === \"query\") {\n const u = new URL(url.toString());\n u.searchParams.set(\"tab\", tab.id);\n href = u.pathname + u.search;\n }\n const active = tab.id === activeId;\n return (\n <NavLink key={tab.id} href={href} onNavigate={p.onNavigate} class={\"bas-tab\" + (active ? \" is-active\" : \"\")} data-testid={`page-tab-${tab.id}`} aria-current={active ? \"page\" : undefined}>\n {tab.label}\n </NavLink>\n );\n })}\n </div>\n );\n}\n\n// ── App shell ──────────────────────────────────────────────────────────────\n\nexport interface AppShellProps {\n brand?: ComponentChildren;\n actions?: ComponentChildren;\n groups: PreactNavGroup[];\n footer?: PreactNavItem[];\n currentPath: string;\n onNavigate?: Navigate;\n /** The notification centre's source. The bell is shown either way. */\n notifications?: NotificationSource;\n user?: ShellUser;\n userMenu?: Omit<UserMenuProps, \"user\" | \"lang\" | \"onNavigate\">;\n /** Phone behaviour: a slide-in drawer, or a 60px icon rail. */\n mobile?: \"drawer\" | \"rail\";\n /**\n * F092.6 — desktop fold: \"offcanvas\" hides the sidebar, \"icon\" keeps a 48px\n * icon rail with `brandMark` on top. Default: \"icon\" when `mobile` is \"rail\".\n */\n collapse?: \"offcanvas\" | \"icon\";\n /** The app's logo icon for the top of the icon rail. */\n brandMark?: ComponentChildren;\n /** F092.7 — the app's start page. Brand and brandMark become links to it; on a phone the click closes the drawer. */\n homeHref?: string;\n /** Accessible name for the brandMark link. Default \"Forside\"/\"Home\". */\n homeLabel?: string;\n /**\n * F092.4 — the page title in the content header, after the sidebar button.\n * Absent: the label of the active nav item (a sub-item wins over its parent).\n */\n title?: ComponentChildren;\n /** localStorage key prefix for the folded sidebar, folded groups and open items. */\n storageKey?: string;\n /** Required: the shell ships no default language (see @broberg/notifications/shell). */\n lang: Lang;\n children?: ComponentChildren;\n}\n\nexport function AppShell(p: AppShellProps) {\n const prefix = p.storageKey ?? \"broberg-app-shell\";\n const mode = p.mobile ?? \"drawer\";\n const collapse = p.collapse ?? (mode === \"rail\" ? \"icon\" : \"offcanvas\");\n const [collapsed, setCollapsed] = useState(() => readFlag(`${prefix}.collapsed`, false));\n const [drawer, setDrawer] = useState(false);\n const isMobile = useIsMobile();\n const t = TEXT[p.lang];\n const toggle = () => {\n const next = !collapsed;\n setCollapsed(next);\n writeFlag(`${prefix}.collapsed`, next);\n };\n // F092.4 — ONE sidebar button: the drawer on a phone, the fold on desktop.\n const drawerMode = isMobile && mode === \"drawer\";\n const onTrigger = () => (drawerMode ? setDrawer(!drawer) : toggle());\n const expanded = drawerMode ? drawer : !collapsed;\n const triggerLabel = drawerMode ? (drawer ? t.closeMenu : t.openMenu) : collapsed ? t.expand : t.collapse;\n const heading = p.title ?? activeNavLabel(p.groups, p.footer, p.currentPath);\n return (\n <div class=\"bas-root\" data-testid=\"app-shell\" data-mobile={mode}>\n <TopBar\n brand={p.brand}\n homeHref={p.homeHref}\n onHome={() => setDrawer(false)}\n actions={p.actions}\n notifications={p.notifications}\n user={p.user}\n userMenu={p.userMenu}\n onNavigate={p.onNavigate}\n lang={p.lang}\n />\n <div class=\"bas-row\">\n <Sidebar\n groups={p.groups}\n footer={p.footer}\n currentPath={p.currentPath}\n onNavigate={p.onNavigate}\n collapsed={collapsed}\n collapse={collapse}\n brandMark={p.brandMark}\n homeHref={p.homeHref}\n homeLabel={p.homeLabel}\n mobileOpen={drawer}\n onClose={() => setDrawer(false)}\n mobile={mode}\n header={mode === \"drawer\" ? p.brand : undefined}\n groupsKey={`${prefix}.groups`}\n itemsKey={`${prefix}.items`}\n lang={p.lang}\n />\n <main class=\"bas-main\" data-testid=\"app-content\">\n <div class=\"bas-contenthead\" data-testid=\"content-header\">\n <button\n type=\"button\"\n class=\"bas-iconbtn bas-trigger\"\n data-testid=\"sidebar-trigger\"\n aria-label={triggerLabel}\n aria-expanded={expanded}\n title={triggerLabel}\n onClick={onTrigger}\n >\n <IconPanelLeft />\n </button>\n {heading ? (\n <>\n <span class=\"bas-contenthead__sep\" data-testid=\"content-header-separator\" aria-hidden=\"true\" />\n <h1 class=\"bas-contenthead__title\" data-testid=\"content-header-title\">\n {heading}\n </h1>\n </>\n ) : null}\n </div>\n {p.children}\n </main>\n </div>\n </div>\n );\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@broberg/app-shell",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.2",
|
|
4
4
|
"description": "The fleet's app shell: collapsible sidebar (phone: rail or drawer), top bar with the notification bell and user menu as standard, page header and tabs. Framework-free core + Preact (Stack B). Styled on @broberg/theme tokens. Avatar from Broberg ID, initials otherwise — no Gravatar.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|