@the-portland-company/shell 0.36.2 → 0.37.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/CHANGELOG.md +18 -0
- package/dist/app-chrome.cjs +134 -24
- package/dist/app-chrome.cjs.map +1 -1
- package/dist/app-chrome.d.cts +8 -1
- package/dist/app-chrome.d.ts +8 -1
- package/dist/app-chrome.js +60 -23
- package/dist/app-chrome.js.map +1 -1
- package/dist/chunk-6UHJV2FH.js +63 -0
- package/dist/chunk-6UHJV2FH.js.map +1 -0
- package/dist/{chunk-LIGKGXFT.js → chunk-CGSS2PDG.js} +20 -6
- package/dist/chunk-CGSS2PDG.js.map +1 -0
- package/dist/native.cjs +18 -3
- package/dist/native.cjs.map +1 -1
- package/dist/native.d.cts +18 -1
- package/dist/native.d.ts +18 -1
- package/dist/native.js +1 -1
- package/dist/nav-preference.cjs +75 -0
- package/dist/nav-preference.cjs.map +1 -0
- package/dist/nav-preference.d.cts +18 -0
- package/dist/nav-preference.d.ts +18 -0
- package/dist/nav-preference.js +3 -0
- package/dist/nav-preference.js.map +1 -0
- package/package.json +6 -1
- package/dist/chunk-LIGKGXFT.js.map +0 -1
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
// src/nav-preference.ts
|
|
2
|
+
var NAV_DISPLAY_STORAGE_KEY = "politogy_nav_display";
|
|
3
|
+
var NAV_DISPLAY_COOKIE = "politogy_nav_display";
|
|
4
|
+
var LEGACY_NAV_DISPLAY_KEY = "vrm.navDisplay";
|
|
5
|
+
var NAV_DISPLAY_DEFAULT = "both";
|
|
6
|
+
var VALID = ["menu", "tabs", "both"];
|
|
7
|
+
function isNavDisplayPreference(v) {
|
|
8
|
+
return typeof v === "string" && VALID.includes(v);
|
|
9
|
+
}
|
|
10
|
+
function readNavDisplayCookie() {
|
|
11
|
+
if (typeof document === "undefined") return null;
|
|
12
|
+
try {
|
|
13
|
+
const m = document.cookie.match(
|
|
14
|
+
new RegExp(`(?:^|;\\s*)${NAV_DISPLAY_COOKIE}=([^;]+)`)
|
|
15
|
+
);
|
|
16
|
+
const v = m ? decodeURIComponent(m[1]) : null;
|
|
17
|
+
return isNavDisplayPreference(v) ? v : null;
|
|
18
|
+
} catch {
|
|
19
|
+
return null;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
function writeNavDisplayCookie(pref) {
|
|
23
|
+
if (typeof document === "undefined" || typeof window === "undefined") return;
|
|
24
|
+
const host = window.location.hostname;
|
|
25
|
+
const domainAttr = /(^|\.)politogyvrm\.com$/i.test(host) ? "; Domain=.politogyvrm.com" : "";
|
|
26
|
+
const secure = window.location.protocol === "https:" ? "; Secure" : "";
|
|
27
|
+
document.cookie = `${NAV_DISPLAY_COOKIE}=${encodeURIComponent(
|
|
28
|
+
pref
|
|
29
|
+
)}; Path=/; Max-Age=31536000; SameSite=Lax${domainAttr}${secure}`;
|
|
30
|
+
}
|
|
31
|
+
function readNavDisplayLocal() {
|
|
32
|
+
if (typeof localStorage === "undefined") return null;
|
|
33
|
+
try {
|
|
34
|
+
const current = localStorage.getItem(NAV_DISPLAY_STORAGE_KEY);
|
|
35
|
+
if (isNavDisplayPreference(current)) return current;
|
|
36
|
+
const legacy = localStorage.getItem(LEGACY_NAV_DISPLAY_KEY);
|
|
37
|
+
return isNavDisplayPreference(legacy) ? legacy : null;
|
|
38
|
+
} catch {
|
|
39
|
+
return null;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
function writeNavDisplayLocal(pref) {
|
|
43
|
+
if (typeof localStorage === "undefined") return;
|
|
44
|
+
try {
|
|
45
|
+
localStorage.setItem(NAV_DISPLAY_STORAGE_KEY, pref);
|
|
46
|
+
} catch {
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
function resolveNavDisplay() {
|
|
50
|
+
return readNavDisplayCookie() ?? readNavDisplayLocal() ?? NAV_DISPLAY_DEFAULT;
|
|
51
|
+
}
|
|
52
|
+
var NAV_DISPLAY_PREPAINT_SCRIPT = `(function(){try{
|
|
53
|
+
var KEY=${JSON.stringify(NAV_DISPLAY_STORAGE_KEY)};
|
|
54
|
+
var VALID=["menu","tabs","both"];
|
|
55
|
+
function fromCookie(){try{var m=document.cookie.match(/(?:^|;\\s*)${NAV_DISPLAY_COOKIE}=([^;]+)/);return m?decodeURIComponent(m[1]):null;}catch(e){return null;}}
|
|
56
|
+
var cookie=fromCookie();
|
|
57
|
+
if(cookie&&VALID.indexOf(cookie)!==-1){var ls=null;try{ls=localStorage.getItem(KEY);}catch(e){}
|
|
58
|
+
if(cookie!==ls){try{localStorage.setItem(KEY,cookie);}catch(e){}}}
|
|
59
|
+
}catch(e){}})();`;
|
|
60
|
+
|
|
61
|
+
export { LEGACY_NAV_DISPLAY_KEY, NAV_DISPLAY_COOKIE, NAV_DISPLAY_DEFAULT, NAV_DISPLAY_PREPAINT_SCRIPT, NAV_DISPLAY_STORAGE_KEY, isNavDisplayPreference, readNavDisplayCookie, readNavDisplayLocal, resolveNavDisplay, writeNavDisplayCookie, writeNavDisplayLocal };
|
|
62
|
+
//# sourceMappingURL=chunk-6UHJV2FH.js.map
|
|
63
|
+
//# sourceMappingURL=chunk-6UHJV2FH.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/nav-preference.ts"],"names":[],"mappings":";AAwBO,IAAM,uBAAA,GAA0B;AAChC,IAAM,kBAAA,GAAqB;AAG3B,IAAM,sBAAA,GAAyB;AAE/B,IAAM,mBAAA,GAA4C;AAEzD,IAAM,KAAA,GAAyC,CAAC,MAAA,EAAQ,MAAA,EAAQ,MAAM,CAAA;AAE/D,SAAS,uBAAuB,CAAA,EAAuC;AAC5E,EAAA,OAAO,OAAO,CAAA,KAAM,QAAA,IAAa,KAAA,CAA4B,SAAS,CAAC,CAAA;AACzE;AAGO,SAAS,oBAAA,GAAoD;AAClE,EAAA,IAAI,OAAO,QAAA,KAAa,WAAA,EAAa,OAAO,IAAA;AAC5C,EAAA,IAAI;AACF,IAAA,MAAM,CAAA,GAAI,SAAS,MAAA,CAAO,KAAA;AAAA,MACxB,IAAI,MAAA,CAAO,CAAA,WAAA,EAAc,kBAAkB,CAAA,QAAA,CAAU;AAAA,KACvD;AACA,IAAA,MAAM,IAAI,CAAA,GAAI,kBAAA,CAAmB,CAAA,CAAE,CAAC,CAAC,CAAA,GAAI,IAAA;AACzC,IAAA,OAAO,sBAAA,CAAuB,CAAC,CAAA,GAAI,CAAA,GAAI,IAAA;AAAA,EACzC,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO,IAAA;AAAA,EACT;AACF;AAMO,SAAS,sBAAsB,IAAA,EAAkC;AACtE,EAAA,IAAI,OAAO,QAAA,KAAa,WAAA,IAAe,OAAO,WAAW,WAAA,EAAa;AACtE,EAAA,MAAM,IAAA,GAAO,OAAO,QAAA,CAAS,QAAA;AAC7B,EAAA,MAAM,UAAA,GAAa,0BAAA,CAA2B,IAAA,CAAK,IAAI,IAAI,2BAAA,GAA8B,EAAA;AACzF,EAAA,MAAM,MAAA,GAAS,MAAA,CAAO,QAAA,CAAS,QAAA,KAAa,WAAW,UAAA,GAAa,EAAA;AACpE,EAAA,QAAA,CAAS,MAAA,GAAS,CAAA,EAAG,kBAAkB,CAAA,CAAA,EAAI,kBAAA;AAAA,IACzC;AAAA,GACD,CAAA,wCAAA,EAA2C,UAAU,CAAA,EAAG,MAAM,CAAA,CAAA;AACjE;AAGO,SAAS,mBAAA,GAAmD;AACjE,EAAA,IAAI,OAAO,YAAA,KAAiB,WAAA,EAAa,OAAO,IAAA;AAChD,EAAA,IAAI;AACF,IAAA,MAAM,OAAA,GAAU,YAAA,CAAa,OAAA,CAAQ,uBAAuB,CAAA;AAC5D,IAAA,IAAI,sBAAA,CAAuB,OAAO,CAAA,EAAG,OAAO,OAAA;AAC5C,IAAA,MAAM,MAAA,GAAS,YAAA,CAAa,OAAA,CAAQ,sBAAsB,CAAA;AAC1D,IAAA,OAAO,sBAAA,CAAuB,MAAM,CAAA,GAAI,MAAA,GAAS,IAAA;AAAA,EACnD,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO,IAAA;AAAA,EACT;AACF;AAEO,SAAS,qBAAqB,IAAA,EAAkC;AACrE,EAAA,IAAI,OAAO,iBAAiB,WAAA,EAAa;AACzC,EAAA,IAAI;AACF,IAAA,YAAA,CAAa,OAAA,CAAQ,yBAAyB,IAAI,CAAA;AAAA,EACpD,CAAA,CAAA,MAAQ;AAAA,EAER;AACF;AAGO,SAAS,iBAAA,GAA0C;AACxD,EAAA,OAAO,oBAAA,EAAqB,IAAK,mBAAA,EAAoB,IAAK,mBAAA;AAC5D;AAMO,IAAM,2BAAA,GAA8B,CAAA;AAAA,QAAA,EACjC,IAAA,CAAK,SAAA,CAAU,uBAAuB,CAAC,CAAA;AAAA;AAAA,kEAAA,EAEmB,kBAAkB,CAAA;AAAA;AAAA;AAAA;AAAA,gBAAA","file":"chunk-6UHJV2FH.js","sourcesContent":["// Universal navigation-display preference — the same cross-app contract as the\n// theme (see ./theme-preference, which this deliberately mirrors).\n//\n// The user's choice of how navigation renders (Menu / Tabs / Both) follows the\n// authenticated user across every Politogy app + subdomain. Three layers:\n// 1. VRM Core `profiles.nav_display_preference` — source of truth, persisted\n// via the chrome API (`PATCH me/preferences { navDisplay }`) and read back\n// from `GET me` (`navDisplay`).\n// 2. `.politogyvrm.com` cookie `politogy_nav_display` — the cross-subdomain\n// vehicle (app session cookies are host-only, and so is localStorage).\n// 3. localStorage — same-app fast reads and cross-tab `storage` events.\n//\n// Before this existed the preference lived ONLY in localStorage under\n// `vrm.navDisplay`, which is per-ORIGIN: every app subdomain kept its own copy\n// and a freshly opened app booted the default, so the setting appeared not to\n// hold when moving between apps. The legacy key is still read as a fallback so\n// an existing local choice survives the upgrade.\n//\n// Server-safe (no 'use client'): layouts may import NAV_DISPLAY_PREPAINT_SCRIPT.\n\nexport type NavDisplayPreference = 'menu' | 'tabs' | 'both'\n\n// One key for BOTH the localStorage store and the cross-subdomain cookie, so a\n// choice in one app is the same key in the next.\nexport const NAV_DISPLAY_STORAGE_KEY = 'politogy_nav_display'\nexport const NAV_DISPLAY_COOKIE = 'politogy_nav_display'\n\n/** Pre-0.37 host-only key. Read for migration; never written. */\nexport const LEGACY_NAV_DISPLAY_KEY = 'vrm.navDisplay'\n\nexport const NAV_DISPLAY_DEFAULT: NavDisplayPreference = 'both'\n\nconst VALID: readonly NavDisplayPreference[] = ['menu', 'tabs', 'both']\n\nexport function isNavDisplayPreference(v: unknown): v is NavDisplayPreference {\n return typeof v === 'string' && (VALID as readonly string[]).includes(v)\n}\n\n/** Read the shared cookie (browser only; null on the server or when unset). */\nexport function readNavDisplayCookie(): NavDisplayPreference | null {\n if (typeof document === 'undefined') return null\n try {\n const m = document.cookie.match(\n new RegExp(`(?:^|;\\\\s*)${NAV_DISPLAY_COOKIE}=([^;]+)`),\n )\n const v = m ? decodeURIComponent(m[1]) : null\n return isNavDisplayPreference(v) ? v : null\n } catch {\n return null\n }\n}\n\n// Same host-aware scoping as the theme cookie: parent domain on\n// *.politogyvrm.com so every app subdomain reads it, host-only elsewhere\n// (localhost, *.pages.dev preview) because browsers silently drop a mismatched\n// Domain attribute. 1-year, SameSite=Lax, Secure on https.\nexport function writeNavDisplayCookie(pref: NavDisplayPreference): void {\n if (typeof document === 'undefined' || typeof window === 'undefined') return\n const host = window.location.hostname\n const domainAttr = /(^|\\.)politogyvrm\\.com$/i.test(host) ? '; Domain=.politogyvrm.com' : ''\n const secure = window.location.protocol === 'https:' ? '; Secure' : ''\n document.cookie = `${NAV_DISPLAY_COOKIE}=${encodeURIComponent(\n pref,\n )}; Path=/; Max-Age=31536000; SameSite=Lax${domainAttr}${secure}`\n}\n\n/** Read the local store, falling back to the legacy host-only key. */\nexport function readNavDisplayLocal(): NavDisplayPreference | null {\n if (typeof localStorage === 'undefined') return null\n try {\n const current = localStorage.getItem(NAV_DISPLAY_STORAGE_KEY)\n if (isNavDisplayPreference(current)) return current\n const legacy = localStorage.getItem(LEGACY_NAV_DISPLAY_KEY)\n return isNavDisplayPreference(legacy) ? legacy : null\n } catch {\n return null\n }\n}\n\nexport function writeNavDisplayLocal(pref: NavDisplayPreference): void {\n if (typeof localStorage === 'undefined') return\n try {\n localStorage.setItem(NAV_DISPLAY_STORAGE_KEY, pref)\n } catch {\n /* storage unavailable */\n }\n}\n\n/** Boot precedence: cookie → localStorage (incl. legacy) → default. */\nexport function resolveNavDisplay(): NavDisplayPreference {\n return readNavDisplayCookie() ?? readNavDisplayLocal() ?? NAV_DISPLAY_DEFAULT\n}\n\n// Inline pre-paint script — optional, and the mirror of THEME_PREPAINT_SCRIPT.\n// Nav display has no paint-blocking visual (the frame is client-rendered), but\n// seeding localStorage from the cookie before hydration keeps the first render\n// on the synced value instead of the default. Self-contained and silent.\nexport const NAV_DISPLAY_PREPAINT_SCRIPT = `(function(){try{\nvar KEY=${JSON.stringify(NAV_DISPLAY_STORAGE_KEY)};\nvar VALID=[\"menu\",\"tabs\",\"both\"];\nfunction fromCookie(){try{var m=document.cookie.match(/(?:^|;\\\\s*)${NAV_DISPLAY_COOKIE}=([^;]+)/);return m?decodeURIComponent(m[1]):null;}catch(e){return null;}}\nvar cookie=fromCookie();\nif(cookie&&VALID.indexOf(cookie)!==-1){var ls=null;try{ls=localStorage.getItem(KEY);}catch(e){}\nif(cookie!==ls){try{localStorage.setItem(KEY,cookie);}catch(e){}}}\n}catch(e){}})();`\n"]}
|
|
@@ -54,6 +54,12 @@ var CORE_APP_ORIGIN = "https://app.politogyvrm.com";
|
|
|
54
54
|
var CORE_BILLING_PATH = "/organization-settings/subscription-billing/text-email";
|
|
55
55
|
var CORE_BILLING_URL = `${CORE_APP_ORIGIN}${CORE_BILLING_PATH}`;
|
|
56
56
|
var QUARANTINED_CONTACTS_URL = `${CORE_APP_ORIGIN}/relationship/contacts/quarantined`;
|
|
57
|
+
function resolveOrgLogoUrl(url) {
|
|
58
|
+
const raw = url?.trim();
|
|
59
|
+
if (!raw) return void 0;
|
|
60
|
+
if (/^(?:[a-z][a-z0-9+.-]*:|\/\/)/i.test(raw)) return raw;
|
|
61
|
+
return `${CORE_APP_ORIGIN}${raw.startsWith("/") ? "" : "/"}${raw}`;
|
|
62
|
+
}
|
|
57
63
|
function topBarIconButtonClass(tone = "default") {
|
|
58
64
|
const toneClass = tone === "danger" || tone === "warning" ? "text-[color:var(--color-race-red)] hover:text-[color:var(--color-race-red)]" : "text-[color:var(--topbar-icon-color,var(--muted))] hover:text-[color:var(--topbar-icon-hover-color,var(--foreground))] hover:bg-[color:var(--topbar-icon-hover-bg,transparent)]";
|
|
59
65
|
return [
|
|
@@ -1492,6 +1498,7 @@ function NavSidebar({
|
|
|
1492
1498
|
const activeFn = nav.isActive ?? isNavItemActive;
|
|
1493
1499
|
const ModeIcon = mode?.icon;
|
|
1494
1500
|
const orgBg = org?.brandColor || ORG_PILL_DEFAULT;
|
|
1501
|
+
const orgLogoSrc = resolveOrgLogoUrl(org?.logoUrl);
|
|
1495
1502
|
const activeGroupKey = useMemo(() => {
|
|
1496
1503
|
for (let i = 0; i < nav.items.length; i++) {
|
|
1497
1504
|
const item = nav.items[i];
|
|
@@ -1559,7 +1566,7 @@ function NavSidebar({
|
|
|
1559
1566
|
{
|
|
1560
1567
|
style: { backgroundColor: orgBg },
|
|
1561
1568
|
className: "flex h-7 w-7 shrink-0 items-center justify-center overflow-hidden rounded-full text-[11px] font-bold text-white",
|
|
1562
|
-
children:
|
|
1569
|
+
children: orgLogoSrc ? /* @__PURE__ */ jsx("img", { src: orgLogoSrc, alt: "", className: "h-full w-full object-cover" }) : (org.name ?? "Org").slice(0, 2).toUpperCase()
|
|
1563
1570
|
}
|
|
1564
1571
|
),
|
|
1565
1572
|
/* @__PURE__ */ jsx(
|
|
@@ -1594,7 +1601,14 @@ function NavSidebar({
|
|
|
1594
1601
|
{
|
|
1595
1602
|
style: { backgroundColor: o.brandColor || ORG_PILL_DEFAULT },
|
|
1596
1603
|
className: "flex h-6 w-6 shrink-0 items-center justify-center overflow-hidden rounded-full text-[10px] font-bold text-white",
|
|
1597
|
-
children: o.logoUrl ? /* @__PURE__ */ jsx(
|
|
1604
|
+
children: resolveOrgLogoUrl(o.logoUrl) ? /* @__PURE__ */ jsx(
|
|
1605
|
+
"img",
|
|
1606
|
+
{
|
|
1607
|
+
src: resolveOrgLogoUrl(o.logoUrl),
|
|
1608
|
+
alt: "",
|
|
1609
|
+
className: "h-full w-full object-cover"
|
|
1610
|
+
}
|
|
1611
|
+
) : (o.name ?? "Org").slice(0, 2).toUpperCase()
|
|
1598
1612
|
}
|
|
1599
1613
|
),
|
|
1600
1614
|
/* @__PURE__ */ jsx("span", { title: o.name ?? o.id, className: "truncate", children: o.name ?? o.id.slice(0, 8) })
|
|
@@ -1616,7 +1630,7 @@ function NavSidebar({
|
|
|
1616
1630
|
{
|
|
1617
1631
|
style: { backgroundColor: orgBg },
|
|
1618
1632
|
className: "flex h-7 w-7 shrink-0 items-center justify-center overflow-hidden rounded-full text-[11px] font-bold text-white",
|
|
1619
|
-
children:
|
|
1633
|
+
children: orgLogoSrc ? /* @__PURE__ */ jsx("img", { src: orgLogoSrc, alt: "", className: "h-full w-full object-cover" }) : (org.name ?? "Org").slice(0, 2).toUpperCase()
|
|
1620
1634
|
}
|
|
1621
1635
|
),
|
|
1622
1636
|
/* @__PURE__ */ jsx("span", { className: "truncate text-sm font-semibold", children: org.name ?? "No organizations" })
|
|
@@ -2490,6 +2504,6 @@ function NavAppShell({
|
|
|
2490
2504
|
] });
|
|
2491
2505
|
}
|
|
2492
2506
|
|
|
2493
|
-
export { CAMPAIGN_FEATURE_AVAILABILITY, CORE_APP_ORIGIN, CORE_BILLING_PATH, FuelAction, NavAppShell, NavBetaBanner, NavChromeProvider, NavDisplayAction, NavSidebar, NavTabStrip, NavThemeControl, NavTopBar, NotificationsAction, SupportAction, TopBarCountBadge, TopBarPanelArrow, TopBarPopover, TopBarTooltip, TopBarWidgetSlot, envChipClasses, isNavItemActive, standardPolitogyNav, topBarIconButtonClass, useChromeMe, useChromeOrgs, useNavChromeFetcher, useThemePreference };
|
|
2494
|
-
//# sourceMappingURL=chunk-
|
|
2495
|
-
//# sourceMappingURL=chunk-
|
|
2507
|
+
export { CAMPAIGN_FEATURE_AVAILABILITY, CORE_APP_ORIGIN, CORE_BILLING_PATH, FuelAction, NavAppShell, NavBetaBanner, NavChromeProvider, NavDisplayAction, NavSidebar, NavTabStrip, NavThemeControl, NavTopBar, NotificationsAction, SupportAction, TopBarCountBadge, TopBarPanelArrow, TopBarPopover, TopBarTooltip, TopBarWidgetSlot, envChipClasses, isNavItemActive, resolveOrgLogoUrl, standardPolitogyNav, topBarIconButtonClass, useChromeMe, useChromeOrgs, useNavChromeFetcher, useThemePreference };
|
|
2508
|
+
//# sourceMappingURL=chunk-CGSS2PDG.js.map
|
|
2509
|
+
//# sourceMappingURL=chunk-CGSS2PDG.js.map
|