kaafil-react-uikit 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/admin/index.cjs +342 -342
- package/dist/admin/index.js +5 -5
- package/dist/{chunk-YHOQRKDJ.cjs → chunk-57SUK3GD.cjs} +7 -7
- package/dist/{chunk-YHOQRKDJ.cjs.map → chunk-57SUK3GD.cjs.map} +1 -1
- package/dist/{chunk-WS2DKREI.cjs → chunk-6WV5VYT2.cjs} +111 -95
- package/dist/chunk-6WV5VYT2.cjs.map +1 -0
- package/dist/{chunk-CURTZGHY.js → chunk-7ISKFGLW.js} +18 -7
- package/dist/chunk-7ISKFGLW.js.map +1 -0
- package/dist/{chunk-W5PG3IUJ.cjs → chunk-7UFX3Y2U.cjs} +4 -4
- package/dist/{chunk-W5PG3IUJ.cjs.map → chunk-7UFX3Y2U.cjs.map} +1 -1
- package/dist/{chunk-2SRBJ4H7.js → chunk-A4Z2YBEF.js} +19 -5
- package/dist/chunk-A4Z2YBEF.js.map +1 -0
- package/dist/{chunk-PYETPKTT.js → chunk-GJ2J3PYN.js} +3 -3
- package/dist/{chunk-PYETPKTT.js.map → chunk-GJ2J3PYN.js.map} +1 -1
- package/dist/{chunk-M2D6CZK2.cjs → chunk-HTIY33UH.cjs} +37 -37
- package/dist/{chunk-M2D6CZK2.cjs.map → chunk-HTIY33UH.cjs.map} +1 -1
- package/dist/{chunk-PDQVVJCS.js → chunk-KW5LH6KV.js} +3 -3
- package/dist/{chunk-PDQVVJCS.js.map → chunk-KW5LH6KV.js.map} +1 -1
- package/dist/{chunk-JMWXQTE3.js → chunk-L3QEMEFM.js} +3 -3
- package/dist/{chunk-JMWXQTE3.js.map → chunk-L3QEMEFM.js.map} +1 -1
- package/dist/{chunk-E42K6UMM.js → chunk-LJJMNZ7B.js} +5 -5
- package/dist/{chunk-E42K6UMM.js.map → chunk-LJJMNZ7B.js.map} +1 -1
- package/dist/{chunk-TF3GCIDK.cjs → chunk-OZJ74DVQ.cjs} +23 -12
- package/dist/chunk-OZJ74DVQ.cjs.map +1 -0
- package/dist/{chunk-2MWTLYVP.cjs → chunk-RG4YDSCN.cjs} +17 -17
- package/dist/{chunk-2MWTLYVP.cjs.map → chunk-RG4YDSCN.cjs.map} +1 -1
- package/dist/{chunk-7WXE5SUS.js → chunk-RSC2ZJUP.js} +35 -19
- package/dist/chunk-RSC2ZJUP.js.map +1 -0
- package/dist/{chunk-FFXGZZGJ.js → chunk-SIAPCJ7G.js} +5 -5
- package/dist/{chunk-FFXGZZGJ.js.map → chunk-SIAPCJ7G.js.map} +1 -1
- package/dist/{chunk-V36WWMTF.cjs → chunk-UALMCHNW.cjs} +19 -5
- package/dist/chunk-UALMCHNW.cjs.map +1 -0
- package/dist/{chunk-PCDEJHWL.cjs → chunk-YNHOPYBK.cjs} +12 -12
- package/dist/{chunk-PCDEJHWL.cjs.map → chunk-YNHOPYBK.cjs.map} +1 -1
- package/dist/core/index.cjs +113 -113
- package/dist/core/index.js +11 -11
- package/dist/manager/index.cjs +239 -239
- package/dist/manager/index.js +6 -6
- package/dist/traveller/index.cjs +35 -35
- package/dist/traveller/index.js +5 -5
- package/package.json +2 -2
- package/dist/chunk-2SRBJ4H7.js.map +0 -1
- package/dist/chunk-7WXE5SUS.js.map +0 -1
- package/dist/chunk-CURTZGHY.js.map +0 -1
- package/dist/chunk-TF3GCIDK.cjs.map +0 -1
- package/dist/chunk-V36WWMTF.cjs.map +0 -1
- package/dist/chunk-WS2DKREI.cjs.map +0 -1
package/dist/admin/index.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { useAgencySettings, useAgencyChecklistTemplates, useAgencyForms, useAgencyManagerProfile, useAgencyJourneyTriggers, useBookings, useDirectories, useCapabilityStatuses, useAgencyTrip, useAgencyAdminMe, useTravellerFormResponses, familySafeSections, useShareLinks, usePaginatedList, useAgencyTrips, useAgencyTripManifest, resolveBlockerDeepLink } from '../chunk-
|
|
2
|
-
import { useChecklists, useFiles, useExpenses, useVendors, useFloat, useManagers, useForms, useItinerary, useCollections, useParties, usePickups, useRooming, useSeating, classifyError, useTravellerProfile, roomingHeuristicSeverity, useManagerToday, useCloseout, parseRoomingTone, TONE_FAMILIES, SHADES_PER_FAMILY, FALLBACK_GLYPH } from '../chunk-
|
|
3
|
-
import '../chunk-
|
|
4
|
-
export { BootErrorScreen, LockedTripScreen, NotFoundScreen, OfflineFallbackScreen, PlanLockedScreen, SessionExpiredScreen } from '../chunk-
|
|
5
|
-
import { createRegistry, useKaafilChrome, tokenStyle, useSession, useKaafilClient } from '../chunk-
|
|
1
|
+
import { useAgencySettings, useAgencyChecklistTemplates, useAgencyForms, useAgencyManagerProfile, useAgencyJourneyTriggers, useBookings, useDirectories, useCapabilityStatuses, useAgencyTrip, useAgencyAdminMe, useTravellerFormResponses, familySafeSections, useShareLinks, usePaginatedList, useAgencyTrips, useAgencyTripManifest, resolveBlockerDeepLink } from '../chunk-SIAPCJ7G.js';
|
|
2
|
+
import { useChecklists, useFiles, useExpenses, useVendors, useFloat, useManagers, useForms, useItinerary, useCollections, useParties, usePickups, useRooming, useSeating, classifyError, useTravellerProfile, roomingHeuristicSeverity, useManagerToday, useCloseout, parseRoomingTone, TONE_FAMILIES, SHADES_PER_FAMILY, FALLBACK_GLYPH } from '../chunk-RSC2ZJUP.js';
|
|
3
|
+
import '../chunk-L3QEMEFM.js';
|
|
4
|
+
export { BootErrorScreen, LockedTripScreen, NotFoundScreen, OfflineFallbackScreen, PlanLockedScreen, SessionExpiredScreen } from '../chunk-GJ2J3PYN.js';
|
|
5
|
+
import { createRegistry, useKaafilChrome, tokenStyle, useSession, useKaafilClient } from '../chunk-A4Z2YBEF.js';
|
|
6
6
|
import { useState, useEffect, useCallback, useMemo, useId, useRef, Children } from 'react';
|
|
7
7
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
8
8
|
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var chunkUALMCHNW_cjs = require('./chunk-UALMCHNW.cjs');
|
|
4
4
|
var react = require('react');
|
|
5
5
|
var jsxRuntime = require('react/jsx-runtime');
|
|
6
6
|
|
|
7
7
|
// src/core/hooks/useOfflineEngine.ts
|
|
8
8
|
function useOfflineEngine() {
|
|
9
|
-
return
|
|
9
|
+
return chunkUALMCHNW_cjs.useRequiredContext(chunkUALMCHNW_cjs.OfflineEngineContext, "useOfflineEngine", "OfflineShell");
|
|
10
10
|
}
|
|
11
11
|
var BrandAssetsContext = react.createContext(null);
|
|
12
12
|
function useKaafilBrand() {
|
|
@@ -68,14 +68,14 @@ function BrandShell({
|
|
|
68
68
|
headStrategy = "none",
|
|
69
69
|
children
|
|
70
70
|
}) {
|
|
71
|
-
const persona =
|
|
71
|
+
const persona = chunkUALMCHNW_cjs.usePersona();
|
|
72
72
|
const assets = react.useMemo(
|
|
73
73
|
() => ({ appName, logo, logoMark, favicon }),
|
|
74
74
|
[appName, logo, logoMark, favicon]
|
|
75
75
|
);
|
|
76
76
|
const rejectedOwnPage = headStrategy === "own-page" && persona !== "share";
|
|
77
77
|
react.useEffect(() => {
|
|
78
|
-
if (headStrategy === "own-page" && persona !== "share" &&
|
|
78
|
+
if (headStrategy === "own-page" && persona !== "share" && chunkUALMCHNW_cjs.isDevelopment()) {
|
|
79
79
|
throw new Error(
|
|
80
80
|
`BrandShell: headStrategy="own-page" was requested under a non-share persona ("${persona}") \u2014 only the traveller/share surface may own document.head (00-decisions.md U-005). Falls back to "none" in production.`
|
|
81
81
|
);
|
|
@@ -86,7 +86,7 @@ function BrandShell({
|
|
|
86
86
|
// work under every `headStrategy` and warning about it told integrators
|
|
87
87
|
// their correct code was wrong. `favicon` has no in-page use at all, so
|
|
88
88
|
// passing one under `'none'` genuinely is a no-op worth flagging.
|
|
89
|
-
favicon !== void 0 &&
|
|
89
|
+
favicon !== void 0 && chunkUALMCHNW_cjs.isDevelopment()) {
|
|
90
90
|
console.warn(
|
|
91
91
|
'BrandShell: headStrategy="none" (the default) is a hard no-op \u2014 "favicon" was passed but document.head is never touched under "none" (00-decisions.md U-005). "appName" is unaffected: it still feeds the in-page brand fallback.'
|
|
92
92
|
);
|
|
@@ -106,5 +106,5 @@ exports.BrandShell = BrandShell;
|
|
|
106
106
|
exports.useKaafilBrand = useKaafilBrand;
|
|
107
107
|
exports.useKaafilShareMeta = useKaafilShareMeta;
|
|
108
108
|
exports.useOfflineEngine = useOfflineEngine;
|
|
109
|
-
//# sourceMappingURL=chunk-
|
|
110
|
-
//# sourceMappingURL=chunk-
|
|
109
|
+
//# sourceMappingURL=chunk-57SUK3GD.cjs.map
|
|
110
|
+
//# sourceMappingURL=chunk-57SUK3GD.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/core/hooks/useOfflineEngine.ts","../src/core/shells/BrandShell.tsx"],"names":["useRequiredContext","OfflineEngineContext","createContext","useContext","useEffect","usePersona","useMemo","isDevelopment","jsxs"],"mappings":"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","file":"chunk-YHOQRKDJ.cjs","sourcesContent":["'use client';\n\n// `08-core-hooks.md §2.1`. The escape hatch underneath every hook in §2 — a\n// composite should reach for a narrower hook before this one.\n\nimport type { OfflineEngine, OutboxOp } from 'kaafil-js/client';\nimport { OfflineEngineContext } from '../internal/contexts';\nimport { useRequiredContext } from '../internal/useRequiredContext';\n\n// Re-exported so a composite (`ManagerSyncCenterSection.types.ts`) can name\n// one outbox op's shape without importing `kaafil-js/client` directly —\n// hard rule #1.\nexport type { OutboxOp };\n\n/** Returns the engine instance `OfflineShell` opened via\n * `client.openOffline(options)`. Throws outside the provider tree. */\nexport function useOfflineEngine(): OfflineEngine {\n return useRequiredContext(OfflineEngineContext, 'useOfflineEngine', 'OfflineShell');\n}\n","'use client';\n\n// `shells/06-brand-shell.md`. Eighth in the locked mount order\n// (`shells/README.md §2` row 8) — supplies host-side brand assets\n// (fallback chain: partner logo → neutral mark → text-only appName,\n// `05-theming-and-branding.md §8`) and, opt-in and persona-gated, controls\n// `document.head` for the traveller/share surface only. Fetches nothing\n// from the engine (`00-decisions.md` U-007 — per-agency brand assets are a\n// named non-goal for the backend).\n\nimport type { ReactNode } from 'react';\nimport { createContext, useContext, useEffect, useMemo } from 'react';\nimport { usePersona } from '../hooks/usePersona';\nimport { isDevelopment } from '../internal/isDevelopment';\n\nexport interface KaafilBrandAssets {\n readonly appName?: string;\n readonly logo?: string | ReactNode;\n readonly logoMark?: string | ReactNode;\n readonly favicon?: string;\n}\n\nexport interface BrandShellProps extends KaafilBrandAssets {\n readonly headStrategy?: 'none' | 'own-page';\n readonly children?: ReactNode;\n}\n\n/** Shell-owned, not a `08-core-hooks.md` catalog entry (component authoring\n * — this context's eventual consumer, a logo/header component reading the\n * fallback chain — is out of scope for this phase). */\nconst BrandAssetsContext = createContext<KaafilBrandAssets | null>(null);\n\n/** Reads the brand assets `BrandShell` forwarded, or `{}` when mounted\n * without one (never throws — brand is presentational, not load-bearing the\n * way a session read is). */\nexport function useKaafilBrand(): KaafilBrandAssets {\n return useContext(BrandAssetsContext) ?? {};\n}\n\nexport interface ShareMeta {\n readonly title: string | undefined;\n readonly favicon: string | undefined;\n readonly ogTitle: string | undefined;\n readonly ogDescription: string | undefined;\n readonly ogImage: string | undefined;\n readonly robots: 'noindex' | 'index';\n}\n\nfunction resolveShareMeta(assets: KaafilBrandAssets): ShareMeta {\n return {\n title: assets.appName,\n favicon: assets.favicon,\n ogTitle: assets.appName,\n ogDescription: undefined,\n ogImage: undefined,\n // Share meta defaults to noindex — a share link is private-by-obscurity;\n // indexing it is a disclosure bug, never the shipped default\n // (`00-decisions.md` U-005).\n robots: 'noindex',\n };\n}\n\n/** Only the traveller/share surface may write `document.head` — mounted\n * exclusively by `BrandShell` under a persona-permitted `'own-page'`\n * request. Renders nothing into the page body: title/meta writes are not\n * \"visual output\" in the sense `shells/README.md §1` means the phrase. */\nfunction KaafilDocumentHead({ meta }: { readonly meta: ShareMeta }): null {\n useEffect(() => {\n if (meta.title !== undefined) {\n document.title = meta.title;\n }\n if (meta.favicon !== undefined) {\n let link = document.querySelector<HTMLLinkElement>('link[rel=\"icon\"][data-kf-brand]');\n if (link === null) {\n link = document.createElement('link');\n link.rel = 'icon';\n link.setAttribute('data-kf-brand', '');\n document.head.appendChild(link);\n }\n link.href = meta.favicon;\n }\n const setMeta = (\n name: string,\n content: string | undefined,\n attr: 'name' | 'property' = 'name',\n ): void => {\n if (content === undefined) {\n return;\n }\n let tag = document.querySelector<HTMLMetaElement>(`meta[${attr}=\"${name}\"][data-kf-brand]`);\n if (tag === null) {\n tag = document.createElement('meta');\n tag.setAttribute(attr, name);\n tag.setAttribute('data-kf-brand', '');\n document.head.appendChild(tag);\n }\n tag.content = content;\n };\n setMeta('og:title', meta.ogTitle, 'property');\n setMeta('og:description', meta.ogDescription, 'property');\n setMeta('og:image', meta.ogImage, 'property');\n setMeta('robots', meta.robots);\n }, [meta]);\n\n return null;\n}\n\n/**\n * Forwards brand assets unconditionally; enforces `headStrategy` before\n * ever mounting `<KaafilDocumentHead>`. `'none'` is a HARD no-op — no\n * branch below it ever touches `document.head`, even when `favicon`/\n * `appName` are supplied. `'own-page'` is runtime-rejected under\n * `agencyAdmin`/`manager` (dev throw, prod warning + silent `'none'`\n * fallback — the same shape `useCapability()` uses for a wrong-persona call,\n * `08-core-hooks.md §1.4`).\n */\nexport function BrandShell({\n appName,\n logo,\n logoMark,\n favicon,\n headStrategy = 'none',\n children,\n}: BrandShellProps): ReactNode {\n const persona = usePersona();\n const assets = useMemo(\n () => ({ appName, logo, logoMark, favicon }),\n [appName, logo, logoMark, favicon],\n );\n\n const rejectedOwnPage = headStrategy === 'own-page' && persona !== 'share';\n\n useEffect(() => {\n if (headStrategy === 'own-page' && persona !== 'share' && isDevelopment()) {\n throw new Error(\n 'BrandShell: headStrategy=\"own-page\" was requested under a non-share persona ' +\n `(\"${persona}\") — only the traveller/share surface may own document.head ` +\n '(00-decisions.md U-005). Falls back to \"none\" in production.',\n );\n }\n if (\n headStrategy === 'none' &&\n // `favicon` ONLY. `appName` is not a head-only prop: it is the last rung\n // of the in-page brand fallback chain (partner logo -> neutral mark ->\n // text-only appName, 05-theming-and-branding.md §8), so it does real\n // work under every `headStrategy` and warning about it told integrators\n // their correct code was wrong. `favicon` has no in-page use at all, so\n // passing one under `'none'` genuinely is a no-op worth flagging.\n favicon !== undefined &&\n isDevelopment()\n ) {\n // biome-ignore lint/suspicious/noConsole: dev-only, gated above by isDevelopment()\n console.warn(\n 'BrandShell: headStrategy=\"none\" (the default) is a hard no-op — \"favicon\" was passed ' +\n 'but document.head is never touched under \"none\" (00-decisions.md U-005). ' +\n '\"appName\" is unaffected: it still feeds the in-page brand fallback.',\n );\n }\n }, [headStrategy, persona, favicon]);\n\n const shouldOwnPage = headStrategy === 'own-page' && persona === 'share' && !rejectedOwnPage;\n\n return (\n <BrandAssetsContext.Provider value={assets}>\n {shouldOwnPage ? <KaafilDocumentHead meta={resolveShareMeta(assets)} /> : null}\n {children}\n </BrandAssetsContext.Provider>\n );\n}\n\n/**\n * Shell-owned read-only alternative to `<KaafilDocumentHead>` — for a host\n * (e.g. Next.js App Router) that already owns `<head>` via its own\n * `metadata`/`generateMetadata` export and must keep `headStrategy=\"none\"`\n * here. Never writes the head itself; exactly one of the two paths is\n * active per mount (`shells/06-brand-shell.md`).\n */\nexport function useKaafilShareMeta(assets: KaafilBrandAssets): ShareMeta {\n return useMemo(() => resolveShareMeta(assets), [assets]);\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/core/hooks/useOfflineEngine.ts","../src/core/shells/BrandShell.tsx"],"names":["useRequiredContext","OfflineEngineContext","createContext","useContext","useEffect","usePersona","useMemo","isDevelopment","jsxs"],"mappings":"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","file":"chunk-57SUK3GD.cjs","sourcesContent":["'use client';\n\n// `08-core-hooks.md §2.1`. The escape hatch underneath every hook in §2 — a\n// composite should reach for a narrower hook before this one.\n\nimport type { OfflineEngine, OutboxOp } from 'kaafil-js/client';\nimport { OfflineEngineContext } from '../internal/contexts';\nimport { useRequiredContext } from '../internal/useRequiredContext';\n\n// Re-exported so a composite (`ManagerSyncCenterSection.types.ts`) can name\n// one outbox op's shape without importing `kaafil-js/client` directly —\n// hard rule #1.\nexport type { OutboxOp };\n\n/** Returns the engine instance `OfflineShell` opened via\n * `client.openOffline(options)`. Throws outside the provider tree. */\nexport function useOfflineEngine(): OfflineEngine {\n return useRequiredContext(OfflineEngineContext, 'useOfflineEngine', 'OfflineShell');\n}\n","'use client';\n\n// `shells/06-brand-shell.md`. Eighth in the locked mount order\n// (`shells/README.md §2` row 8) — supplies host-side brand assets\n// (fallback chain: partner logo → neutral mark → text-only appName,\n// `05-theming-and-branding.md §8`) and, opt-in and persona-gated, controls\n// `document.head` for the traveller/share surface only. Fetches nothing\n// from the engine (`00-decisions.md` U-007 — per-agency brand assets are a\n// named non-goal for the backend).\n\nimport type { ReactNode } from 'react';\nimport { createContext, useContext, useEffect, useMemo } from 'react';\nimport { usePersona } from '../hooks/usePersona';\nimport { isDevelopment } from '../internal/isDevelopment';\n\nexport interface KaafilBrandAssets {\n readonly appName?: string;\n readonly logo?: string | ReactNode;\n readonly logoMark?: string | ReactNode;\n readonly favicon?: string;\n}\n\nexport interface BrandShellProps extends KaafilBrandAssets {\n readonly headStrategy?: 'none' | 'own-page';\n readonly children?: ReactNode;\n}\n\n/** Shell-owned, not a `08-core-hooks.md` catalog entry (component authoring\n * — this context's eventual consumer, a logo/header component reading the\n * fallback chain — is out of scope for this phase). */\nconst BrandAssetsContext = createContext<KaafilBrandAssets | null>(null);\n\n/** Reads the brand assets `BrandShell` forwarded, or `{}` when mounted\n * without one (never throws — brand is presentational, not load-bearing the\n * way a session read is). */\nexport function useKaafilBrand(): KaafilBrandAssets {\n return useContext(BrandAssetsContext) ?? {};\n}\n\nexport interface ShareMeta {\n readonly title: string | undefined;\n readonly favicon: string | undefined;\n readonly ogTitle: string | undefined;\n readonly ogDescription: string | undefined;\n readonly ogImage: string | undefined;\n readonly robots: 'noindex' | 'index';\n}\n\nfunction resolveShareMeta(assets: KaafilBrandAssets): ShareMeta {\n return {\n title: assets.appName,\n favicon: assets.favicon,\n ogTitle: assets.appName,\n ogDescription: undefined,\n ogImage: undefined,\n // Share meta defaults to noindex — a share link is private-by-obscurity;\n // indexing it is a disclosure bug, never the shipped default\n // (`00-decisions.md` U-005).\n robots: 'noindex',\n };\n}\n\n/** Only the traveller/share surface may write `document.head` — mounted\n * exclusively by `BrandShell` under a persona-permitted `'own-page'`\n * request. Renders nothing into the page body: title/meta writes are not\n * \"visual output\" in the sense `shells/README.md §1` means the phrase. */\nfunction KaafilDocumentHead({ meta }: { readonly meta: ShareMeta }): null {\n useEffect(() => {\n if (meta.title !== undefined) {\n document.title = meta.title;\n }\n if (meta.favicon !== undefined) {\n let link = document.querySelector<HTMLLinkElement>('link[rel=\"icon\"][data-kf-brand]');\n if (link === null) {\n link = document.createElement('link');\n link.rel = 'icon';\n link.setAttribute('data-kf-brand', '');\n document.head.appendChild(link);\n }\n link.href = meta.favicon;\n }\n const setMeta = (\n name: string,\n content: string | undefined,\n attr: 'name' | 'property' = 'name',\n ): void => {\n if (content === undefined) {\n return;\n }\n let tag = document.querySelector<HTMLMetaElement>(`meta[${attr}=\"${name}\"][data-kf-brand]`);\n if (tag === null) {\n tag = document.createElement('meta');\n tag.setAttribute(attr, name);\n tag.setAttribute('data-kf-brand', '');\n document.head.appendChild(tag);\n }\n tag.content = content;\n };\n setMeta('og:title', meta.ogTitle, 'property');\n setMeta('og:description', meta.ogDescription, 'property');\n setMeta('og:image', meta.ogImage, 'property');\n setMeta('robots', meta.robots);\n }, [meta]);\n\n return null;\n}\n\n/**\n * Forwards brand assets unconditionally; enforces `headStrategy` before\n * ever mounting `<KaafilDocumentHead>`. `'none'` is a HARD no-op — no\n * branch below it ever touches `document.head`, even when `favicon`/\n * `appName` are supplied. `'own-page'` is runtime-rejected under\n * `agencyAdmin`/`manager` (dev throw, prod warning + silent `'none'`\n * fallback — the same shape `useCapability()` uses for a wrong-persona call,\n * `08-core-hooks.md §1.4`).\n */\nexport function BrandShell({\n appName,\n logo,\n logoMark,\n favicon,\n headStrategy = 'none',\n children,\n}: BrandShellProps): ReactNode {\n const persona = usePersona();\n const assets = useMemo(\n () => ({ appName, logo, logoMark, favicon }),\n [appName, logo, logoMark, favicon],\n );\n\n const rejectedOwnPage = headStrategy === 'own-page' && persona !== 'share';\n\n useEffect(() => {\n if (headStrategy === 'own-page' && persona !== 'share' && isDevelopment()) {\n throw new Error(\n 'BrandShell: headStrategy=\"own-page\" was requested under a non-share persona ' +\n `(\"${persona}\") — only the traveller/share surface may own document.head ` +\n '(00-decisions.md U-005). Falls back to \"none\" in production.',\n );\n }\n if (\n headStrategy === 'none' &&\n // `favicon` ONLY. `appName` is not a head-only prop: it is the last rung\n // of the in-page brand fallback chain (partner logo -> neutral mark ->\n // text-only appName, 05-theming-and-branding.md §8), so it does real\n // work under every `headStrategy` and warning about it told integrators\n // their correct code was wrong. `favicon` has no in-page use at all, so\n // passing one under `'none'` genuinely is a no-op worth flagging.\n favicon !== undefined &&\n isDevelopment()\n ) {\n // biome-ignore lint/suspicious/noConsole: dev-only, gated above by isDevelopment()\n console.warn(\n 'BrandShell: headStrategy=\"none\" (the default) is a hard no-op — \"favicon\" was passed ' +\n 'but document.head is never touched under \"none\" (00-decisions.md U-005). ' +\n '\"appName\" is unaffected: it still feeds the in-page brand fallback.',\n );\n }\n }, [headStrategy, persona, favicon]);\n\n const shouldOwnPage = headStrategy === 'own-page' && persona === 'share' && !rejectedOwnPage;\n\n return (\n <BrandAssetsContext.Provider value={assets}>\n {shouldOwnPage ? <KaafilDocumentHead meta={resolveShareMeta(assets)} /> : null}\n {children}\n </BrandAssetsContext.Provider>\n );\n}\n\n/**\n * Shell-owned read-only alternative to `<KaafilDocumentHead>` — for a host\n * (e.g. Next.js App Router) that already owns `<head>` via its own\n * `metadata`/`generateMetadata` export and must keep `headStrategy=\"none\"`\n * here. Never writes the head itself; exactly one of the two paths is\n * active per mount (`shells/06-brand-shell.md`).\n */\nexport function useKaafilShareMeta(assets: KaafilBrandAssets): ShareMeta {\n return useMemo(() => resolveShareMeta(assets), [assets]);\n}\n"]}
|