@the-portland-company/shell 0.64.0 → 0.65.1
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/app-chrome.cjs +289 -256
- package/dist/app-chrome.cjs.map +1 -1
- package/dist/app-chrome.js +3 -3
- package/dist/app-chrome.js.map +1 -1
- package/dist/chrome.css +22 -95
- package/dist/{chunk-U4RZPZET.js → chunk-JHIFJZ73.js} +9 -16
- package/dist/chunk-JHIFJZ73.js.map +1 -0
- package/dist/{chunk-LFLN5GD6.js → chunk-NRKRUM5B.js} +278 -238
- package/dist/chunk-NRKRUM5B.js.map +1 -0
- package/dist/index.cjs +5 -12
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +1 -1
- package/dist/native.cjs +288 -255
- package/dist/native.cjs.map +1 -1
- package/dist/native.d.cts +21 -1
- package/dist/native.d.ts +21 -1
- package/dist/native.js +2 -2
- package/dist/theme-preference.cjs +7 -14
- package/dist/theme-preference.cjs.map +1 -1
- package/dist/theme-preference.d.cts +3 -1
- package/dist/theme-preference.d.ts +3 -1
- package/dist/theme-preference.js +1 -1
- package/package.json +1 -1
- package/dist/chunk-LFLN5GD6.js.map +0 -1
- package/dist/chunk-U4RZPZET.js.map +0 -1
package/dist/app-chrome.cjs
CHANGED
|
@@ -131,20 +131,13 @@ function clearPendingThemeChoice() {
|
|
|
131
131
|
writeSharedCookie(THEME_PENDING_COOKIE, "", 0);
|
|
132
132
|
}
|
|
133
133
|
function resolveTheme(pref) {
|
|
134
|
-
|
|
135
|
-
try {
|
|
136
|
-
return window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light";
|
|
137
|
-
} catch {
|
|
138
|
-
return "light";
|
|
139
|
-
}
|
|
140
|
-
}
|
|
141
|
-
return pref;
|
|
134
|
+
return "light";
|
|
142
135
|
}
|
|
143
136
|
function applyThemePreference(pref) {
|
|
144
137
|
if (typeof document === "undefined") return;
|
|
145
|
-
const resolved = resolveTheme(
|
|
138
|
+
const resolved = resolveTheme();
|
|
146
139
|
const d = document.documentElement;
|
|
147
|
-
d.classList.
|
|
140
|
+
d.classList.remove("dark");
|
|
148
141
|
try {
|
|
149
142
|
d.style.colorScheme = resolved;
|
|
150
143
|
} catch {
|
|
@@ -159,11 +152,11 @@ var ls=null;try{ls=localStorage.getItem(KEY);}catch(e){}
|
|
|
159
152
|
var pref=cookie||ls||"system";
|
|
160
153
|
if(VALID.indexOf(pref)===-1)pref="system";
|
|
161
154
|
if(cookie&&cookie!==ls){try{localStorage.setItem(KEY,cookie);}catch(e){}}
|
|
162
|
-
|
|
163
|
-
|
|
155
|
+
// Dark Mode retired platform-wide 2026-09-21 \u2014 always light, and strip any
|
|
156
|
+
// stale dark class a pre-retirement cookie/localStorage value left behind.
|
|
164
157
|
var d=document.documentElement;
|
|
165
|
-
|
|
166
|
-
try{d.style.colorScheme=
|
|
158
|
+
d.classList.remove("dark");
|
|
159
|
+
try{d.style.colorScheme="light";}catch(e){}
|
|
167
160
|
}catch(e){}})();`;
|
|
168
161
|
var CORE_APP_ORIGIN = "https://app.politogyvrm.com";
|
|
169
162
|
var CORE_BILLING_PATH = "/organization-settings/subscription-billing/text-email";
|
|
@@ -1375,11 +1368,14 @@ function useLocationHref() {
|
|
|
1375
1368
|
return href;
|
|
1376
1369
|
}
|
|
1377
1370
|
function specOverlayFetchJson(path) {
|
|
1378
|
-
return fetch(`${SPECS_ORIGIN}${path}`, { credentials: "include" }).then((res) => {
|
|
1371
|
+
return fetch(`${SPECS_ORIGIN}${path}`, { credentials: "include", signal: AbortSignal.timeout(1e4) }).then((res) => {
|
|
1379
1372
|
if (!res.ok) throw new Error(`spec overlay ${path}: ${res.status}`);
|
|
1380
1373
|
return res.json();
|
|
1381
1374
|
});
|
|
1382
1375
|
}
|
|
1376
|
+
function isAutomatedCaptureSession() {
|
|
1377
|
+
return typeof navigator !== "undefined" && navigator.webdriver === true;
|
|
1378
|
+
}
|
|
1383
1379
|
function currentChromeTheme() {
|
|
1384
1380
|
const root = document.documentElement;
|
|
1385
1381
|
if (root.classList.contains("dark") || root.getAttribute("data-theme") === "dark") return "dark";
|
|
@@ -1431,7 +1427,8 @@ async function captureMyView(status, orgId, orgName) {
|
|
|
1431
1427
|
method: "POST",
|
|
1432
1428
|
credentials: "include",
|
|
1433
1429
|
headers: { "X-Spec-Capture": "1" },
|
|
1434
|
-
body: form
|
|
1430
|
+
body: form,
|
|
1431
|
+
signal: AbortSignal.timeout(1e4)
|
|
1435
1432
|
});
|
|
1436
1433
|
if (!res.ok) throw new Error(`capture ${res.status}: ${(await res.text()).slice(0, 160)}`);
|
|
1437
1434
|
}
|
|
@@ -1464,8 +1461,9 @@ function SpecOverlayAction({ orgId, orgName } = {}) {
|
|
|
1464
1461
|
const [frameKey, setFrameKey] = react.useState(0);
|
|
1465
1462
|
const [copied, setCopied] = react.useState("idle");
|
|
1466
1463
|
const href = useLocationHref();
|
|
1464
|
+
const automated = isAutomatedCaptureSession();
|
|
1467
1465
|
react.useEffect(() => {
|
|
1468
|
-
if (access) return;
|
|
1466
|
+
if (access || automated) return;
|
|
1469
1467
|
let cancelled = false;
|
|
1470
1468
|
specOverlayFetchJson("/api/overlay/access").then((data) => {
|
|
1471
1469
|
if (cancelled) return;
|
|
@@ -1483,7 +1481,7 @@ function SpecOverlayAction({ orgId, orgName } = {}) {
|
|
|
1483
1481
|
};
|
|
1484
1482
|
}, [access]);
|
|
1485
1483
|
react.useEffect(() => {
|
|
1486
|
-
if (!access?.allowed || typeof window === "undefined") return;
|
|
1484
|
+
if (automated || !access?.allowed || typeof window === "undefined") return;
|
|
1487
1485
|
const timer = window.setTimeout(() => {
|
|
1488
1486
|
specOverlayFetchJson(specOverlayStatusPath()).then((data) => setStatus(data)).catch(() => setStatus(null));
|
|
1489
1487
|
}, 300);
|
|
@@ -1514,13 +1512,13 @@ function SpecOverlayAction({ orgId, orgName } = {}) {
|
|
|
1514
1512
|
}
|
|
1515
1513
|
};
|
|
1516
1514
|
react.useEffect(() => {
|
|
1517
|
-
if (!open || !status || !status.matched) return;
|
|
1515
|
+
if (automated || !open || !status || !status.matched) return;
|
|
1518
1516
|
void runCapture(status);
|
|
1519
1517
|
return () => {
|
|
1520
1518
|
captureRun.current++;
|
|
1521
1519
|
};
|
|
1522
1520
|
}, [open, status && status.matched ? status.target_id : null]);
|
|
1523
|
-
if (!access?.allowed) return null;
|
|
1521
|
+
if (automated || !access?.allowed) return null;
|
|
1524
1522
|
const badgeLabel = status && status.matched ? `${Math.round(status.mismatch_pct)}%` : status ? "\u2014" : void 0;
|
|
1525
1523
|
const badgeTone = status && status.matched ? status.passed ? "default" : "danger" : "default";
|
|
1526
1524
|
return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
@@ -1744,7 +1742,7 @@ function useThemePreference() {
|
|
|
1744
1742
|
}
|
|
1745
1743
|
const pref = cookie ?? (isThemePreference(ls) ? ls : null) ?? "system";
|
|
1746
1744
|
setValueState(pref);
|
|
1747
|
-
applyThemePreference(
|
|
1745
|
+
applyThemePreference();
|
|
1748
1746
|
}, []);
|
|
1749
1747
|
const meCtx = react.useContext(NavChromeContext);
|
|
1750
1748
|
react.useEffect(() => {
|
|
@@ -1753,7 +1751,7 @@ function useThemePreference() {
|
|
|
1753
1751
|
if (pending) {
|
|
1754
1752
|
if (meCtx?.me) reconciled.current = true;
|
|
1755
1753
|
setValueState(pending);
|
|
1756
|
-
applyThemePreference(
|
|
1754
|
+
applyThemePreference();
|
|
1757
1755
|
writeThemeCookie(pending);
|
|
1758
1756
|
try {
|
|
1759
1757
|
localStorage.setItem(THEME_STORAGE_KEY, pending);
|
|
@@ -1772,7 +1770,7 @@ function useThemePreference() {
|
|
|
1772
1770
|
if (isThemePreference(pref)) {
|
|
1773
1771
|
reconciled.current = true;
|
|
1774
1772
|
setValueState(pref);
|
|
1775
|
-
applyThemePreference(
|
|
1773
|
+
applyThemePreference();
|
|
1776
1774
|
writeThemeCookie(pref);
|
|
1777
1775
|
try {
|
|
1778
1776
|
localStorage.setItem(THEME_STORAGE_KEY, pref);
|
|
@@ -1791,7 +1789,7 @@ function useThemePreference() {
|
|
|
1791
1789
|
const cookie = readThemeCookie();
|
|
1792
1790
|
if (cookie) {
|
|
1793
1791
|
setValueState((prev) => {
|
|
1794
|
-
if (cookie !== prev) applyThemePreference(
|
|
1792
|
+
if (cookie !== prev) applyThemePreference();
|
|
1795
1793
|
return cookie;
|
|
1796
1794
|
});
|
|
1797
1795
|
}
|
|
@@ -1813,14 +1811,14 @@ function useThemePreference() {
|
|
|
1813
1811
|
} catch {
|
|
1814
1812
|
return;
|
|
1815
1813
|
}
|
|
1816
|
-
const onChange = () => applyThemePreference(
|
|
1814
|
+
const onChange = () => applyThemePreference();
|
|
1817
1815
|
mq.addEventListener("change", onChange);
|
|
1818
1816
|
return () => mq.removeEventListener("change", onChange);
|
|
1819
1817
|
}, [value]);
|
|
1820
1818
|
const setValue = react.useCallback(
|
|
1821
1819
|
(next) => {
|
|
1822
1820
|
setValueState(next);
|
|
1823
|
-
applyThemePreference(
|
|
1821
|
+
applyThemePreference();
|
|
1824
1822
|
writeThemeCookie(next);
|
|
1825
1823
|
try {
|
|
1826
1824
|
localStorage.setItem(THEME_STORAGE_KEY, next);
|
|
@@ -2433,52 +2431,34 @@ function NavSidebar({
|
|
|
2433
2431
|
}
|
|
2434
2432
|
)
|
|
2435
2433
|
] }) : null,
|
|
2436
|
-
mode ? /* @__PURE__ */ jsxRuntime.
|
|
2437
|
-
/* @__PURE__ */ jsxRuntime.
|
|
2438
|
-
|
|
2439
|
-
|
|
2440
|
-
|
|
2441
|
-
|
|
2442
|
-
|
|
2443
|
-
|
|
2444
|
-
|
|
2445
|
-
|
|
2446
|
-
|
|
2447
|
-
|
|
2448
|
-
|
|
2449
|
-
|
|
2450
|
-
|
|
2451
|
-
|
|
2452
|
-
|
|
2453
|
-
|
|
2434
|
+
mode ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mb-4", children: [
|
|
2435
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center justify-center gap-2 rounded-md bg-[color:var(--panel-elevated)] p-1", children: (mode.options && mode.options.length > 0 ? mode.options : [{ id: mode.label, label: mode.label, icon: ModeIcon }]).map(
|
|
2436
|
+
(opt) => {
|
|
2437
|
+
const selected = opt.label === mode.label;
|
|
2438
|
+
const OptIcon = opt.icon;
|
|
2439
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
2440
|
+
"button",
|
|
2441
|
+
{
|
|
2442
|
+
type: "button",
|
|
2443
|
+
title: opt.label,
|
|
2444
|
+
"aria-label": opt.label,
|
|
2445
|
+
"aria-current": selected ? "true" : void 0,
|
|
2446
|
+
onClick: () => {
|
|
2447
|
+
if (!selected) mode.onSelect?.(opt.id);
|
|
2448
|
+
},
|
|
2449
|
+
disabled: !mode.onSelect && !selected,
|
|
2450
|
+
className: [
|
|
2451
|
+
"flex h-9 flex-1 items-center justify-center rounded transition",
|
|
2452
|
+
selected ? "bg-[color:var(--mode-accent,var(--color-accent))] text-[color:var(--mode-on-accent,white)] shadow-sm" : "text-[color:var(--sidebar-text-muted,var(--muted))] hover:bg-[color:var(--panel)] hover:text-[color:var(--sidebar-text,var(--foreground))]"
|
|
2453
|
+
].join(" "),
|
|
2454
|
+
children: OptIcon ? /* @__PURE__ */ jsxRuntime.jsx(OptIcon, { size: 16, className: "shrink-0" }) : null
|
|
2454
2455
|
},
|
|
2455
|
-
|
|
2456
|
-
|
|
2457
|
-
|
|
2458
|
-
|
|
2459
|
-
|
|
2460
|
-
|
|
2461
|
-
OptIcon ? /* @__PURE__ */ jsxRuntime.jsx(OptIcon, { size: 15, className: "shrink-0 text-current" }) : null,
|
|
2462
|
-
opt.label
|
|
2463
|
-
]
|
|
2464
|
-
},
|
|
2465
|
-
opt.id
|
|
2466
|
-
);
|
|
2467
|
-
}) })
|
|
2468
|
-
] }) : /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2469
|
-
"button",
|
|
2470
|
-
{
|
|
2471
|
-
type: "button",
|
|
2472
|
-
className: "flex w-full items-center justify-between gap-2 rounded-md bg-[color:var(--mode-accent,var(--color-accent))] px-2.5 py-2 text-[color:var(--mode-on-accent,white)] shadow-sm",
|
|
2473
|
-
children: [
|
|
2474
|
-
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "flex items-center gap-2.5", children: [
|
|
2475
|
-
ModeIcon ? /* @__PURE__ */ jsxRuntime.jsx(ModeIcon, { size: 16, className: "shrink-0" }) : null,
|
|
2476
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm font-semibold tracking-[-0.01em]", children: mode.label })
|
|
2477
|
-
] }),
|
|
2478
|
-
/* @__PURE__ */ jsxRuntime.jsx(ChevronDown, {})
|
|
2479
|
-
]
|
|
2480
|
-
}
|
|
2481
|
-
) }) : null,
|
|
2456
|
+
opt.id
|
|
2457
|
+
);
|
|
2458
|
+
}
|
|
2459
|
+
) }),
|
|
2460
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "mt-1.5 text-center text-[11px] font-semibold uppercase tracking-[0.08em] text-[color:var(--sidebar-text-muted,var(--muted))]", children: mode.label })
|
|
2461
|
+
] }) : null,
|
|
2482
2462
|
/* @__PURE__ */ jsxRuntime.jsxs("nav", { className: "flex flex-col gap-1", children: [
|
|
2483
2463
|
nav.groupLabel ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: "px-2 pb-1 text-[11px] font-semibold uppercase tracking-[0.08em] text-[color:var(--sidebar-text-muted,var(--muted))]", children: nav.groupLabel }) : null,
|
|
2484
2464
|
nav.items.map((item, idx) => {
|
|
@@ -2626,6 +2606,27 @@ function HamburgerIcon() {
|
|
|
2626
2606
|
}
|
|
2627
2607
|
);
|
|
2628
2608
|
}
|
|
2609
|
+
function SearchIcon({ className } = {}) {
|
|
2610
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2611
|
+
"svg",
|
|
2612
|
+
{
|
|
2613
|
+
width: 16,
|
|
2614
|
+
height: 16,
|
|
2615
|
+
viewBox: "0 0 24 24",
|
|
2616
|
+
fill: "none",
|
|
2617
|
+
stroke: "currentColor",
|
|
2618
|
+
strokeWidth: 2,
|
|
2619
|
+
strokeLinecap: "round",
|
|
2620
|
+
strokeLinejoin: "round",
|
|
2621
|
+
className,
|
|
2622
|
+
"aria-hidden": "true",
|
|
2623
|
+
children: [
|
|
2624
|
+
/* @__PURE__ */ jsxRuntime.jsx("circle", { cx: "11", cy: "11", r: "7" }),
|
|
2625
|
+
/* @__PURE__ */ jsxRuntime.jsx("line", { x1: "21", y1: "21", x2: "16.65", y2: "16.65" })
|
|
2626
|
+
]
|
|
2627
|
+
}
|
|
2628
|
+
);
|
|
2629
|
+
}
|
|
2629
2630
|
function CloseIcon() {
|
|
2630
2631
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2631
2632
|
"svg",
|
|
@@ -2920,214 +2921,231 @@ function NavTopBar({
|
|
|
2920
2921
|
actions,
|
|
2921
2922
|
themeToggle,
|
|
2922
2923
|
onOpenNav,
|
|
2923
|
-
navOpen
|
|
2924
|
+
navOpen,
|
|
2925
|
+
search,
|
|
2926
|
+
buildNotes
|
|
2924
2927
|
}) {
|
|
2925
2928
|
const rawName = user?.name?.trim() || "";
|
|
2926
2929
|
const hasRealName = rawName.length > 0 && !rawName.includes("@");
|
|
2927
2930
|
const displayName = hasRealName ? formatFirstLast(rawName) : user?.email ?? "Signed in";
|
|
2928
2931
|
const initials = (hasRealName ? rawName : user?.email ?? "P").slice(0, 2).toUpperCase();
|
|
2929
2932
|
const secondary = hasRealName ? user?.email || [user?.tier, user?.role].filter(Boolean).join(" \xB7 ") || "member" : [user?.tier, user?.role].filter(Boolean).join(" \xB7 ") || "member";
|
|
2930
|
-
return /* @__PURE__ */ jsxRuntime.jsxs("
|
|
2931
|
-
|
|
2932
|
-
|
|
2933
|
-
|
|
2934
|
-
type: "button",
|
|
2935
|
-
onClick: onOpenNav,
|
|
2936
|
-
"aria-label": "Open menu",
|
|
2937
|
-
"aria-expanded": navOpen ?? false,
|
|
2938
|
-
"aria-controls": "politogy-nav-drawer",
|
|
2939
|
-
className: `${topBarIconButtonClass("default")} mr-3 shrink-0 lg:hidden lg:mr-0`,
|
|
2940
|
-
children: /* @__PURE__ */ jsxRuntime.jsx(HamburgerIcon, {})
|
|
2941
|
-
}
|
|
2942
|
-
) : null,
|
|
2943
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "min-w-0", children: [
|
|
2944
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2945
|
-
"h1",
|
|
2933
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "sticky top-0 z-20", children: [
|
|
2934
|
+
/* @__PURE__ */ jsxRuntime.jsxs("header", { className: "flex h-[var(--topbar-height,60px)] items-center justify-between gap-4 border-b border-[color:var(--line)] bg-[color:var(--panel)] px-[var(--topbar-padding-x,20px)]", children: [
|
|
2935
|
+
onOpenNav ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
2936
|
+
"button",
|
|
2946
2937
|
{
|
|
2947
|
-
|
|
2948
|
-
|
|
2949
|
-
|
|
2938
|
+
type: "button",
|
|
2939
|
+
onClick: onOpenNav,
|
|
2940
|
+
"aria-label": "Open menu",
|
|
2941
|
+
"aria-expanded": navOpen ?? false,
|
|
2942
|
+
"aria-controls": "politogy-nav-drawer",
|
|
2943
|
+
className: `${topBarIconButtonClass("default")} mr-1 shrink-0 lg:hidden`,
|
|
2944
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(HamburgerIcon, {})
|
|
2950
2945
|
}
|
|
2951
|
-
),
|
|
2952
|
-
|
|
2953
|
-
|
|
2954
|
-
|
|
2955
|
-
|
|
2956
|
-
|
|
2957
|
-
"
|
|
2958
|
-
|
|
2959
|
-
|
|
2960
|
-
|
|
2961
|
-
|
|
2962
|
-
|
|
2963
|
-
|
|
2964
|
-
|
|
2965
|
-
|
|
2966
|
-
|
|
2967
|
-
|
|
2968
|
-
|
|
2969
|
-
|
|
2970
|
-
|
|
2971
|
-
|
|
2972
|
-
|
|
2973
|
-
|
|
2974
|
-
|
|
2975
|
-
|
|
2976
|
-
|
|
2977
|
-
|
|
2978
|
-
|
|
2979
|
-
|
|
2980
|
-
|
|
2981
|
-
"
|
|
2982
|
-
|
|
2983
|
-
|
|
2984
|
-
|
|
2985
|
-
|
|
2986
|
-
|
|
2987
|
-
|
|
2988
|
-
|
|
2989
|
-
|
|
2990
|
-
|
|
2991
|
-
]
|
|
2992
|
-
|
|
2993
|
-
|
|
2994
|
-
TopBarTooltip,
|
|
2995
|
-
{
|
|
2996
|
-
title: "My Account",
|
|
2997
|
-
description: /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
2998
|
-
hasRealName ? rawName : user?.email ?? "Signed in",
|
|
2999
|
-
user?.email ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
3000
|
-
/* @__PURE__ */ jsxRuntime.jsx("br", {}),
|
|
3001
|
-
user.email
|
|
3002
|
-
] }) : null,
|
|
3003
|
-
/* @__PURE__ */ jsxRuntime.jsx("br", {}),
|
|
3004
|
-
"Profile, organizations, appearance and sign out."
|
|
3005
|
-
] })
|
|
3006
|
-
}
|
|
3007
|
-
) })
|
|
3008
|
-
] }),
|
|
3009
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "absolute right-0 z-30 mt-2 flex max-h-[calc(100vh-5rem)] w-72 flex-col overflow-hidden rounded-xl border border-[color:var(--line)] bg-[color:var(--panel-elevated)] py-1 shadow-[var(--shadow-soft)]", children: [
|
|
3010
|
-
/* @__PURE__ */ jsxRuntime.jsx(TopBarPanelArrow, {}),
|
|
3011
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "min-h-0 flex-1 overflow-y-auto overscroll-contain", children: [
|
|
3012
|
-
userMenu?.myProfileHref ? /* @__PURE__ */ jsxRuntime.jsxs(
|
|
3013
|
-
"a",
|
|
2946
|
+
) : null,
|
|
2947
|
+
/* @__PURE__ */ jsxRuntime.jsxs("label", { className: "relative flex w-[320px] max-w-full shrink-0 items-center", children: [
|
|
2948
|
+
/* @__PURE__ */ jsxRuntime.jsx(SearchIcon, { className: "pointer-events-none absolute left-3 h-4 w-4 text-[color:var(--muted)]" }),
|
|
2949
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2950
|
+
"input",
|
|
2951
|
+
{
|
|
2952
|
+
type: "search",
|
|
2953
|
+
placeholder: search?.placeholder ?? "Search",
|
|
2954
|
+
value: search?.value,
|
|
2955
|
+
onChange: search?.onChange ? (e) => search.onChange?.(e.target.value) : void 0,
|
|
2956
|
+
onKeyDown: search?.onSubmit ? (e) => {
|
|
2957
|
+
if (e.key === "Enter") search.onSubmit?.(e.target.value);
|
|
2958
|
+
} : void 0,
|
|
2959
|
+
readOnly: !search?.onChange,
|
|
2960
|
+
className: "w-full rounded-md border border-[color:var(--line)] bg-[color:var(--panel-elevated)] py-1.5 pl-9 pr-10 text-sm text-[color:var(--foreground)] placeholder:text-[color:var(--muted)] focus:outline-none focus:ring-2 focus:ring-[color:var(--color-accent)]"
|
|
2961
|
+
}
|
|
2962
|
+
),
|
|
2963
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2964
|
+
"kbd",
|
|
2965
|
+
{
|
|
2966
|
+
"aria-hidden": true,
|
|
2967
|
+
className: "pointer-events-none absolute right-2.5 rounded border border-[color:var(--line)] px-1 py-0.5 text-[10px] font-medium text-[color:var(--muted)]",
|
|
2968
|
+
children: "/"
|
|
2969
|
+
}
|
|
2970
|
+
)
|
|
2971
|
+
] }),
|
|
2972
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative ml-auto flex shrink-0 items-center gap-[var(--topbar-icon-gap,8px)]", children: [
|
|
2973
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2974
|
+
"button",
|
|
2975
|
+
{
|
|
2976
|
+
type: "button",
|
|
2977
|
+
onClick: buildNotes?.onOpen,
|
|
2978
|
+
className: "shrink-0 rounded-md px-2 py-1.5 text-sm font-medium text-[color:var(--muted)] transition hover:bg-[color:var(--panel-elevated)] hover:text-[color:var(--foreground)]",
|
|
2979
|
+
children: buildNotes?.label ?? "Build notes"
|
|
2980
|
+
}
|
|
2981
|
+
),
|
|
2982
|
+
actionsList && actionsList.length > 0 ? actionsList.map((action) => /* @__PURE__ */ jsxRuntime.jsx(NavTopBarActionButton, { action }, action.key)) : null,
|
|
2983
|
+
actions,
|
|
2984
|
+
themeToggle,
|
|
2985
|
+
/* @__PURE__ */ jsxRuntime.jsxs("details", { "data-nav-details": true, className: "group/acct relative", children: [
|
|
2986
|
+
/* @__PURE__ */ jsxRuntime.jsxs("summary", { className: "group/tbtip relative flex cursor-pointer list-none items-center gap-2.5 rounded-full py-1 pl-1 pr-2 transition hover:bg-[color:var(--panel-elevated)] [&::-webkit-details-marker]:hidden", children: [
|
|
2987
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex h-[var(--topbar-icon-button-size,32px)] w-[var(--topbar-icon-button-size,32px)] items-center justify-center overflow-hidden rounded-full bg-[color:var(--color-accent)] text-xs font-bold text-white", children: user?.avatarUrl || user?.memojiUrl ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
2988
|
+
"img",
|
|
3014
2989
|
{
|
|
3015
|
-
|
|
3016
|
-
|
|
3017
|
-
|
|
3018
|
-
/* @__PURE__ */ jsxRuntime.jsx(ProfileIcon, {}),
|
|
3019
|
-
"My Profile"
|
|
3020
|
-
]
|
|
2990
|
+
src: user.avatarUrl || user.memojiUrl,
|
|
2991
|
+
alt: "",
|
|
2992
|
+
className: "h-full w-full object-cover"
|
|
3021
2993
|
}
|
|
3022
|
-
) :
|
|
3023
|
-
|
|
3024
|
-
"
|
|
2994
|
+
) : initials }),
|
|
2995
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "hidden flex-col leading-tight md:flex", children: [
|
|
2996
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm font-semibold text-[color:var(--foreground)]", children: displayName }),
|
|
2997
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs text-[color:var(--muted)]", children: secondary })
|
|
2998
|
+
] }),
|
|
2999
|
+
/* @__PURE__ */ jsxRuntime.jsx(ChevronDown, {}),
|
|
3000
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "group-open/acct:hidden", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
3001
|
+
TopBarTooltip,
|
|
3025
3002
|
{
|
|
3026
|
-
|
|
3027
|
-
|
|
3028
|
-
|
|
3029
|
-
/* @__PURE__ */ jsxRuntime.
|
|
3030
|
-
|
|
3031
|
-
|
|
3003
|
+
title: "My Account",
|
|
3004
|
+
description: /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
3005
|
+
hasRealName ? rawName : user?.email ?? "Signed in",
|
|
3006
|
+
user?.email ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
3007
|
+
/* @__PURE__ */ jsxRuntime.jsx("br", {}),
|
|
3008
|
+
user.email
|
|
3009
|
+
] }) : null,
|
|
3010
|
+
/* @__PURE__ */ jsxRuntime.jsx("br", {}),
|
|
3011
|
+
"Profile, organizations, appearance and sign out."
|
|
3012
|
+
] })
|
|
3032
3013
|
}
|
|
3033
|
-
)
|
|
3034
|
-
|
|
3035
|
-
|
|
3036
|
-
|
|
3037
|
-
|
|
3038
|
-
|
|
3039
|
-
|
|
3040
|
-
|
|
3041
|
-
|
|
3042
|
-
|
|
3043
|
-
|
|
3044
|
-
|
|
3045
|
-
|
|
3046
|
-
|
|
3047
|
-
|
|
3048
|
-
|
|
3014
|
+
) })
|
|
3015
|
+
] }),
|
|
3016
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "absolute right-0 z-30 mt-2 flex max-h-[calc(100vh-5rem)] w-72 flex-col overflow-hidden rounded-xl border border-[color:var(--line)] bg-[color:var(--panel-elevated)] py-1 shadow-[var(--shadow-soft)]", children: [
|
|
3017
|
+
/* @__PURE__ */ jsxRuntime.jsx(TopBarPanelArrow, {}),
|
|
3018
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "min-h-0 flex-1 overflow-y-auto overscroll-contain", children: [
|
|
3019
|
+
userMenu?.myProfileHref ? /* @__PURE__ */ jsxRuntime.jsxs(
|
|
3020
|
+
"a",
|
|
3021
|
+
{
|
|
3022
|
+
href: safeHref(userMenu.myProfileHref),
|
|
3023
|
+
className: "flex w-full items-center gap-2.5 px-4 py-2.5 text-left text-sm font-medium text-[color:var(--foreground)] hover:bg-[color:var(--panel)]",
|
|
3024
|
+
children: [
|
|
3025
|
+
/* @__PURE__ */ jsxRuntime.jsx(ProfileIcon, {}),
|
|
3026
|
+
"My Profile"
|
|
3027
|
+
]
|
|
3028
|
+
}
|
|
3029
|
+
) : null,
|
|
3030
|
+
userMenu?.organizationSettingsHref ? /* @__PURE__ */ jsxRuntime.jsxs(
|
|
3031
|
+
"a",
|
|
3032
|
+
{
|
|
3033
|
+
href: safeHref(userMenu.organizationSettingsHref),
|
|
3034
|
+
className: "flex w-full items-center gap-2.5 border-t border-[color:var(--line)] px-4 py-2.5 text-left text-sm font-medium text-[color:var(--foreground)] hover:bg-[color:var(--panel)]",
|
|
3035
|
+
children: [
|
|
3036
|
+
/* @__PURE__ */ jsxRuntime.jsx(BriefcaseIcon, {}),
|
|
3037
|
+
"Organization Settings"
|
|
3038
|
+
]
|
|
3039
|
+
}
|
|
3040
|
+
) : null,
|
|
3041
|
+
userMenu?.roles && userMenu.roles.length > 0 ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "border-t border-[color:var(--line)] px-4 py-3", children: [
|
|
3042
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "mb-2 text-[11px] font-semibold uppercase tracking-[0.08em] text-[color:var(--muted)]", children: "Roles & Organizations" }),
|
|
3043
|
+
/* @__PURE__ */ jsxRuntime.jsx("ul", { className: "flex flex-col gap-1.5", children: userMenu.roles.map((r, i) => /* @__PURE__ */ jsxRuntime.jsxs("li", { className: "flex flex-wrap items-center gap-1.5 text-sm", children: [
|
|
3044
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "rounded-md bg-[color:var(--panel)] px-2 py-0.5 text-xs font-bold uppercase tracking-wide text-[color:var(--foreground)]", children: r.role }),
|
|
3045
|
+
r.orgName ? /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-[color:var(--muted)]", children: [
|
|
3046
|
+
"in ",
|
|
3047
|
+
r.orgName
|
|
3048
|
+
] }) : null
|
|
3049
|
+
] }, `${r.role}-${i}`)) })
|
|
3050
|
+
] }) : null,
|
|
3051
|
+
userMenu?.accounts && userMenu.accounts.length > 0 ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "border-t border-[color:var(--line)] px-4 py-3", children: [
|
|
3052
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "mb-2 text-[11px] font-semibold uppercase tracking-[0.08em] text-[color:var(--muted)]", children: "Accounts" }),
|
|
3053
|
+
/* @__PURE__ */ jsxRuntime.jsx("ul", { className: "flex flex-col gap-1", children: userMenu.accounts.map((a) => /* @__PURE__ */ jsxRuntime.jsxs("li", { className: "flex items-center gap-2.5", children: [
|
|
3054
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
3055
|
+
"button",
|
|
3056
|
+
{
|
|
3057
|
+
type: "button",
|
|
3058
|
+
onClick: () => {
|
|
3059
|
+
if (!a.active) userMenu.onSwitchAccount?.(a.id);
|
|
3060
|
+
},
|
|
3061
|
+
className: "flex min-w-0 flex-1 items-center gap-2.5 rounded-lg px-1 py-1 text-left hover:bg-[color:var(--panel)]",
|
|
3062
|
+
children: [
|
|
3063
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex h-8 w-8 shrink-0 items-center justify-center overflow-hidden rounded-full bg-[color:var(--color-accent)] text-[11px] font-bold text-white", children: a.avatarUrl ? /* @__PURE__ */ jsxRuntime.jsx("img", { src: a.avatarUrl, alt: "", className: "h-full w-full object-cover" }) : (a.name ?? a.email ?? "?").slice(0, 2).toUpperCase() }),
|
|
3064
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "flex min-w-0 flex-col leading-tight", children: [
|
|
3065
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3066
|
+
"span",
|
|
3067
|
+
{
|
|
3068
|
+
className: [
|
|
3069
|
+
"truncate text-sm font-semibold",
|
|
3070
|
+
a.active ? "text-[color:var(--color-accent)]" : "text-[color:var(--foreground)]"
|
|
3071
|
+
].join(" "),
|
|
3072
|
+
children: a.name ?? a.email ?? a.id.slice(0, 8)
|
|
3073
|
+
}
|
|
3074
|
+
),
|
|
3075
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate text-xs text-[color:var(--muted)]", children: a.active ? "Active" : a.email ?? "" })
|
|
3076
|
+
] })
|
|
3077
|
+
]
|
|
3078
|
+
}
|
|
3079
|
+
),
|
|
3080
|
+
!a.active && userMenu.onRemoveAccount ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
3081
|
+
"button",
|
|
3082
|
+
{
|
|
3083
|
+
type: "button",
|
|
3084
|
+
"aria-label": `Remove ${a.name ?? a.email ?? "account"}`,
|
|
3085
|
+
onClick: () => userMenu.onRemoveAccount?.(a.id),
|
|
3086
|
+
className: "shrink-0 rounded p-1 text-[color:var(--color-accent)] hover:bg-[color:var(--panel)]",
|
|
3087
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(TrashIcon, {})
|
|
3088
|
+
}
|
|
3089
|
+
) : null
|
|
3090
|
+
] }, a.id)) }),
|
|
3091
|
+
userMenu.addAccountHref || userMenu.onAddAccount ? userMenu.addAccountHref ? /* @__PURE__ */ jsxRuntime.jsxs(
|
|
3092
|
+
"a",
|
|
3049
3093
|
{
|
|
3050
|
-
|
|
3051
|
-
|
|
3052
|
-
if (!a.active) userMenu.onSwitchAccount?.(a.id);
|
|
3053
|
-
},
|
|
3054
|
-
className: "flex min-w-0 flex-1 items-center gap-2.5 rounded-lg px-1 py-1 text-left hover:bg-[color:var(--panel)]",
|
|
3094
|
+
href: safeHref(userMenu.addAccountHref),
|
|
3095
|
+
className: "mt-1.5 flex items-center gap-2.5 rounded-lg px-1 py-1.5 text-sm font-semibold text-[color:var(--color-accent)] hover:bg-[color:var(--panel)]",
|
|
3055
3096
|
children: [
|
|
3056
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3057
|
-
|
|
3058
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3059
|
-
"span",
|
|
3060
|
-
{
|
|
3061
|
-
className: [
|
|
3062
|
-
"truncate text-sm font-semibold",
|
|
3063
|
-
a.active ? "text-[color:var(--color-accent)]" : "text-[color:var(--foreground)]"
|
|
3064
|
-
].join(" "),
|
|
3065
|
-
children: a.name ?? a.email ?? a.id.slice(0, 8)
|
|
3066
|
-
}
|
|
3067
|
-
),
|
|
3068
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate text-xs text-[color:var(--muted)]", children: a.active ? "Active" : a.email ?? "" })
|
|
3069
|
-
] })
|
|
3097
|
+
/* @__PURE__ */ jsxRuntime.jsx(AddUserIcon, {}),
|
|
3098
|
+
"Add Account"
|
|
3070
3099
|
]
|
|
3071
3100
|
}
|
|
3072
|
-
)
|
|
3073
|
-
!a.active && userMenu.onRemoveAccount ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
3101
|
+
) : /* @__PURE__ */ jsxRuntime.jsxs(
|
|
3074
3102
|
"button",
|
|
3075
3103
|
{
|
|
3076
3104
|
type: "button",
|
|
3077
|
-
|
|
3078
|
-
|
|
3079
|
-
|
|
3080
|
-
|
|
3105
|
+
onClick: userMenu.onAddAccount,
|
|
3106
|
+
className: "mt-1.5 flex w-full items-center gap-2.5 rounded-lg px-1 py-1.5 text-left text-sm font-semibold text-[color:var(--color-accent)] hover:bg-[color:var(--panel)]",
|
|
3107
|
+
children: [
|
|
3108
|
+
/* @__PURE__ */ jsxRuntime.jsx(AddUserIcon, {}),
|
|
3109
|
+
"Add Account"
|
|
3110
|
+
]
|
|
3081
3111
|
}
|
|
3082
3112
|
) : null
|
|
3083
|
-
] }
|
|
3084
|
-
userMenu
|
|
3085
|
-
|
|
3086
|
-
{
|
|
3087
|
-
href: safeHref(userMenu.addAccountHref),
|
|
3088
|
-
className: "mt-1.5 flex items-center gap-2.5 rounded-lg px-1 py-1.5 text-sm font-semibold text-[color:var(--color-accent)] hover:bg-[color:var(--panel)]",
|
|
3089
|
-
children: [
|
|
3090
|
-
/* @__PURE__ */ jsxRuntime.jsx(AddUserIcon, {}),
|
|
3091
|
-
"Add Account"
|
|
3092
|
-
]
|
|
3093
|
-
}
|
|
3094
|
-
) : /* @__PURE__ */ jsxRuntime.jsxs(
|
|
3095
|
-
"button",
|
|
3113
|
+
] }) : null,
|
|
3114
|
+
userMenu?.theme ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "border-t border-[color:var(--line)]", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
3115
|
+
NavThemeControl,
|
|
3096
3116
|
{
|
|
3097
|
-
|
|
3098
|
-
|
|
3099
|
-
className: "mt-1.5 flex w-full items-center gap-2.5 rounded-lg px-1 py-1.5 text-left text-sm font-semibold text-[color:var(--color-accent)] hover:bg-[color:var(--panel)]",
|
|
3100
|
-
children: [
|
|
3101
|
-
/* @__PURE__ */ jsxRuntime.jsx(AddUserIcon, {}),
|
|
3102
|
-
"Add Account"
|
|
3103
|
-
]
|
|
3117
|
+
value: userMenu.theme.value,
|
|
3118
|
+
onChange: userMenu.theme.onChange
|
|
3104
3119
|
}
|
|
3105
|
-
) : null
|
|
3106
|
-
] })
|
|
3107
|
-
|
|
3108
|
-
|
|
3120
|
+
) }) : null
|
|
3121
|
+
] }),
|
|
3122
|
+
onSignOut ? /* @__PURE__ */ jsxRuntime.jsxs(
|
|
3123
|
+
"button",
|
|
3109
3124
|
{
|
|
3110
|
-
|
|
3111
|
-
|
|
3125
|
+
type: "button",
|
|
3126
|
+
onClick: onSignOut,
|
|
3127
|
+
className: "flex w-full shrink-0 items-center gap-2.5 border-t border-[color:var(--line)] px-4 py-2.5 text-left text-sm font-medium text-[color:var(--foreground)] hover:bg-[color:var(--panel)] hover:text-[color:var(--color-accent)]",
|
|
3128
|
+
children: [
|
|
3129
|
+
/* @__PURE__ */ jsxRuntime.jsx(SignOutIcon, {}),
|
|
3130
|
+
"Sign out"
|
|
3131
|
+
]
|
|
3112
3132
|
}
|
|
3113
|
-
)
|
|
3114
|
-
] })
|
|
3115
|
-
|
|
3116
|
-
|
|
3117
|
-
|
|
3118
|
-
|
|
3119
|
-
|
|
3120
|
-
|
|
3121
|
-
|
|
3122
|
-
|
|
3123
|
-
|
|
3124
|
-
|
|
3125
|
-
|
|
3126
|
-
|
|
3127
|
-
|
|
3128
|
-
|
|
3129
|
-
!hasRealName && user ? /* @__PURE__ */ jsxRuntime.jsx(NamePromptBubble, { profileHref: userMenu?.myProfileHref }) : null
|
|
3130
|
-
] })
|
|
3133
|
+
) : null
|
|
3134
|
+
] })
|
|
3135
|
+
] }),
|
|
3136
|
+
!hasRealName && user ? /* @__PURE__ */ jsxRuntime.jsx(NamePromptBubble, { profileHref: userMenu?.myProfileHref }) : null
|
|
3137
|
+
] })
|
|
3138
|
+
] }),
|
|
3139
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3140
|
+
"div",
|
|
3141
|
+
{
|
|
3142
|
+
"aria-hidden": true,
|
|
3143
|
+
className: "h-[3px] w-full shrink-0",
|
|
3144
|
+
style: {
|
|
3145
|
+
background: "var(--chrome-gradient, linear-gradient(to right, #007BFF, #A54B7A, #E63946))"
|
|
3146
|
+
}
|
|
3147
|
+
}
|
|
3148
|
+
)
|
|
3131
3149
|
] });
|
|
3132
3150
|
}
|
|
3133
3151
|
function NamePromptBubble({ profileHref }) {
|
|
@@ -3391,7 +3409,22 @@ function NavAppShell({
|
|
|
3391
3409
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "lg:pl-[240px]", children: [
|
|
3392
3410
|
/* @__PURE__ */ jsxRuntime.jsx(NavTopBar, { ...topBar, onOpenNav: () => setNavOpen(true), navOpen }),
|
|
3393
3411
|
betaBanner ? /* @__PURE__ */ jsxRuntime.jsx(NavBetaBanner, { ...betaBanner }) : null,
|
|
3394
|
-
|
|
3412
|
+
topBar.title ? /* @__PURE__ */ jsxRuntime.jsx("h1", { className: "px-6 pt-7 text-xl font-semibold text-[color:var(--foreground)]", children: topBar.title }) : null,
|
|
3413
|
+
contentWrapper === "bare" ? /* @__PURE__ */ jsxRuntime.jsx("div", { "data-shell-content": "", className: topBar.title ? "mt-[22px]" : void 0, children }) : (
|
|
3414
|
+
// Claude Design: "a rounded, inset frame on a light-grey page
|
|
3415
|
+
// background" — the shell owns the page background and the
|
|
3416
|
+
// gutter; it does not draw a hard border/box around the content
|
|
3417
|
+
// (that reads as a second frame on top of the page header). An
|
|
3418
|
+
// app's own cards are its own furniture and stay app-owned.
|
|
3419
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3420
|
+
"main",
|
|
3421
|
+
{
|
|
3422
|
+
"data-shell-content": "",
|
|
3423
|
+
className: `min-h-[calc(100vh-63px)] bg-[color:var(--chrome-page-bg,#F4F5F7)] px-6 ${topBar.title ? "pb-7 pt-[22px]" : "py-7"}`,
|
|
3424
|
+
children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mx-auto max-w-7xl", children })
|
|
3425
|
+
}
|
|
3426
|
+
)
|
|
3427
|
+
)
|
|
3395
3428
|
] })
|
|
3396
3429
|
]
|
|
3397
3430
|
}
|
|
@@ -4324,7 +4357,7 @@ function FrameBody({
|
|
|
4324
4357
|
footer,
|
|
4325
4358
|
linkComponent
|
|
4326
4359
|
},
|
|
4327
|
-
betaBanner: meta.beta ===
|
|
4360
|
+
betaBanner: meta.beta === true ? {} : void 0,
|
|
4328
4361
|
modeId: appMode,
|
|
4329
4362
|
contentWrapper: core?.contentWrapper ?? granted("contentWrapper"),
|
|
4330
4363
|
topBar: {
|