@the-portland-company/shell 0.68.1 → 0.70.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 +56 -0
- package/README.md +4 -1
- package/dist/FormColumn-DsNP6NVG.d.cts +21 -0
- package/dist/FormColumn-DsNP6NVG.d.ts +21 -0
- package/dist/app-chrome.cjs +477 -236
- package/dist/app-chrome.cjs.map +1 -1
- package/dist/app-chrome.d.cts +24 -12
- package/dist/app-chrome.d.ts +24 -12
- package/dist/app-chrome.js +115 -50
- package/dist/app-chrome.js.map +1 -1
- package/dist/app-icons.cjs +6 -10
- package/dist/app-icons.cjs.map +1 -1
- package/dist/app-icons.d.cts +6 -6
- package/dist/app-icons.d.ts +6 -6
- package/dist/app-icons.js +6 -10
- package/dist/app-icons.js.map +1 -1
- package/dist/{chunk-6UHJV2FH.js → chunk-7YVJ7HQG.js} +41 -3
- package/dist/chunk-7YVJ7HQG.js.map +1 -0
- package/dist/{chunk-2UTIX3LI.js → chunk-CZI66JVG.js} +278 -167
- package/dist/chunk-CZI66JVG.js.map +1 -0
- package/dist/chunk-LPSBSAF3.js +26 -0
- package/dist/chunk-LPSBSAF3.js.map +1 -0
- package/dist/index.cjs +68 -37
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +30 -9
- package/dist/index.d.ts +30 -9
- package/dist/index.js +59 -45
- package/dist/index.js.map +1 -1
- package/dist/native.cjs +343 -165
- package/dist/native.cjs.map +1 -1
- package/dist/native.d.cts +69 -31
- package/dist/native.d.ts +69 -31
- package/dist/native.js +3 -1
- package/dist/nav-preference.cjs +44 -0
- package/dist/nav-preference.cjs.map +1 -1
- package/dist/nav-preference.d.cts +8 -1
- package/dist/nav-preference.d.ts +8 -1
- package/dist/nav-preference.js +1 -1
- package/package.json +1 -1
- package/dist/chunk-2UTIX3LI.js.map +0 -1
- package/dist/chunk-6UHJV2FH.js.map +0 -1
package/dist/app-chrome.cjs
CHANGED
|
@@ -7,6 +7,7 @@ var fi = require('react-icons/fi');
|
|
|
7
7
|
var reactDom = require('react-dom');
|
|
8
8
|
var jsxRuntime = require('react/jsx-runtime');
|
|
9
9
|
var devnotes = require('@the-portland-company/devnotes');
|
|
10
|
+
var lu = require('react-icons/lu');
|
|
10
11
|
|
|
11
12
|
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
12
13
|
|
|
@@ -59,6 +60,21 @@ function resolveBrandGlyph(name) {
|
|
|
59
60
|
return GLYPHS[name.trim().toLowerCase()] ?? null;
|
|
60
61
|
}
|
|
61
62
|
|
|
63
|
+
// src/lib/deprecation.ts
|
|
64
|
+
var warned = /* @__PURE__ */ new Set();
|
|
65
|
+
function isDev() {
|
|
66
|
+
try {
|
|
67
|
+
return typeof process !== "undefined" && process.env?.NODE_ENV !== "production";
|
|
68
|
+
} catch {
|
|
69
|
+
return false;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
function warnDeprecated(key, message) {
|
|
73
|
+
if (!isDev() || warned.has(key)) return;
|
|
74
|
+
warned.add(key);
|
|
75
|
+
console.warn(`[@the-portland-company/shell] ${message}`);
|
|
76
|
+
}
|
|
77
|
+
|
|
62
78
|
// src/native/orgFilter.ts
|
|
63
79
|
var ORG_FILTER_THRESHOLD = 8;
|
|
64
80
|
function filterOrgs(orgs, query) {
|
|
@@ -73,13 +89,111 @@ function normalize(s) {
|
|
|
73
89
|
return s.normalize("NFD").replace(/[̀-ͯ]/g, "").toLowerCase().trim();
|
|
74
90
|
}
|
|
75
91
|
|
|
92
|
+
// src/nav-preference.ts
|
|
93
|
+
var NAV_DISPLAY_STORAGE_KEY = "politogy_nav_display";
|
|
94
|
+
var NAV_DISPLAY_COOKIE = "politogy_nav_display";
|
|
95
|
+
var LEGACY_NAV_DISPLAY_KEY = "vrm.navDisplay";
|
|
96
|
+
var NAV_DISPLAY_DEFAULT = "both";
|
|
97
|
+
var VALID = ["menu", "tabs", "both"];
|
|
98
|
+
function isNavDisplayPreference(v) {
|
|
99
|
+
return typeof v === "string" && VALID.includes(v);
|
|
100
|
+
}
|
|
101
|
+
function readNavDisplayCookie() {
|
|
102
|
+
if (typeof document === "undefined") return null;
|
|
103
|
+
try {
|
|
104
|
+
const m = document.cookie.match(
|
|
105
|
+
new RegExp(`(?:^|;\\s*)${NAV_DISPLAY_COOKIE}=([^;]+)`)
|
|
106
|
+
);
|
|
107
|
+
const v = m ? decodeURIComponent(m[1]) : null;
|
|
108
|
+
return isNavDisplayPreference(v) ? v : null;
|
|
109
|
+
} catch {
|
|
110
|
+
return null;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
function writeNavDisplayCookie(pref) {
|
|
114
|
+
if (typeof document === "undefined" || typeof window === "undefined") return;
|
|
115
|
+
const host = window.location.hostname;
|
|
116
|
+
const domainAttr = /(^|\.)politogyvrm\.com$/i.test(host) ? "; Domain=.politogyvrm.com" : "";
|
|
117
|
+
const secure = window.location.protocol === "https:" ? "; Secure" : "";
|
|
118
|
+
document.cookie = `${NAV_DISPLAY_COOKIE}=${encodeURIComponent(
|
|
119
|
+
pref
|
|
120
|
+
)}; Path=/; Max-Age=31536000; SameSite=Lax${domainAttr}${secure}`;
|
|
121
|
+
}
|
|
122
|
+
function readNavDisplayLocal() {
|
|
123
|
+
if (typeof localStorage === "undefined") return null;
|
|
124
|
+
try {
|
|
125
|
+
const current = localStorage.getItem(NAV_DISPLAY_STORAGE_KEY);
|
|
126
|
+
if (isNavDisplayPreference(current)) return current;
|
|
127
|
+
const legacy = localStorage.getItem(LEGACY_NAV_DISPLAY_KEY);
|
|
128
|
+
return isNavDisplayPreference(legacy) ? legacy : null;
|
|
129
|
+
} catch {
|
|
130
|
+
return null;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
function writeNavDisplayLocal(pref) {
|
|
134
|
+
if (typeof localStorage === "undefined") return;
|
|
135
|
+
try {
|
|
136
|
+
localStorage.setItem(NAV_DISPLAY_STORAGE_KEY, pref);
|
|
137
|
+
} catch {
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
function resolveNavDisplay() {
|
|
141
|
+
return readNavDisplayCookie() ?? readNavDisplayLocal() ?? NAV_DISPLAY_DEFAULT;
|
|
142
|
+
}
|
|
143
|
+
`(function(){try{
|
|
144
|
+
var KEY=${JSON.stringify(NAV_DISPLAY_STORAGE_KEY)};
|
|
145
|
+
var VALID=["menu","tabs","both"];
|
|
146
|
+
function fromCookie(){try{var m=document.cookie.match(/(?:^|;\\s*)${NAV_DISPLAY_COOKIE}=([^;]+)/);return m?decodeURIComponent(m[1]):null;}catch(e){return null;}}
|
|
147
|
+
var cookie=fromCookie();
|
|
148
|
+
if(cookie&&VALID.indexOf(cookie)!==-1){var ls=null;try{ls=localStorage.getItem(KEY);}catch(e){}
|
|
149
|
+
if(cookie!==ls){try{localStorage.setItem(KEY,cookie);}catch(e){}}}
|
|
150
|
+
}catch(e){}})();`;
|
|
151
|
+
var RAIL_STORAGE_KEY = "politogy_rail";
|
|
152
|
+
var RAIL_COOKIE = "politogy_rail";
|
|
153
|
+
var RAIL_DEFAULT = "collapsed";
|
|
154
|
+
function isRailPreference(v) {
|
|
155
|
+
return v === "expanded" || v === "collapsed";
|
|
156
|
+
}
|
|
157
|
+
function readRailPreference() {
|
|
158
|
+
if (typeof document !== "undefined") {
|
|
159
|
+
try {
|
|
160
|
+
const m = document.cookie.match(new RegExp(`(?:^|;\\s*)${RAIL_COOKIE}=([^;]+)`));
|
|
161
|
+
const v = m ? decodeURIComponent(m[1]) : null;
|
|
162
|
+
if (isRailPreference(v)) return v;
|
|
163
|
+
} catch {
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
if (typeof localStorage !== "undefined") {
|
|
167
|
+
try {
|
|
168
|
+
const v = localStorage.getItem(RAIL_STORAGE_KEY);
|
|
169
|
+
if (isRailPreference(v)) return v;
|
|
170
|
+
} catch {
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
return RAIL_DEFAULT;
|
|
174
|
+
}
|
|
175
|
+
function writeRailPreference(pref) {
|
|
176
|
+
if (typeof document === "undefined" || typeof window === "undefined") return;
|
|
177
|
+
const host = window.location.hostname;
|
|
178
|
+
const domainAttr = /(^|\.)politogyvrm\.com$/i.test(host) ? "; Domain=.politogyvrm.com" : "";
|
|
179
|
+
const secure = window.location.protocol === "https:" ? "; Secure" : "";
|
|
180
|
+
try {
|
|
181
|
+
document.cookie = `${RAIL_COOKIE}=${pref}; Path=/; Max-Age=31536000; SameSite=Lax${domainAttr}${secure}`;
|
|
182
|
+
} catch {
|
|
183
|
+
}
|
|
184
|
+
try {
|
|
185
|
+
localStorage.setItem(RAIL_STORAGE_KEY, pref);
|
|
186
|
+
} catch {
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
|
|
76
190
|
// src/theme-preference.ts
|
|
77
191
|
var THEME_STORAGE_KEY = "politogy_theme";
|
|
78
192
|
var THEME_COOKIE = "politogy_theme";
|
|
79
193
|
var THEME_PENDING_COOKIE = "politogy_theme_pending";
|
|
80
|
-
var
|
|
194
|
+
var VALID2 = ["light", "dark", "system"];
|
|
81
195
|
function isThemePreference(v) {
|
|
82
|
-
return typeof v === "string" &&
|
|
196
|
+
return typeof v === "string" && VALID2.includes(v);
|
|
83
197
|
}
|
|
84
198
|
function readThemeCookie() {
|
|
85
199
|
if (typeof document === "undefined") return null;
|
|
@@ -1832,7 +1946,6 @@ var PHONEBANK_ORIGIN = "https://phonebank.politogyvrm.com/";
|
|
|
1832
1946
|
var CANVASS_ORIGIN = "https://canvass.politogyvrm.com/";
|
|
1833
1947
|
var SIGNS_ORIGIN = "https://signs.politogyvrm.com/";
|
|
1834
1948
|
var POLLS_ORIGIN = "https://polls.politogyvrm.com/";
|
|
1835
|
-
var CONTACTS_TRIBES = "https://contacts.politogyvrm.com/tribes";
|
|
1836
1949
|
var PETITION_MODE_ORIGIN = "https://petition-mode.politogyvrm.com/";
|
|
1837
1950
|
function applyHiddenItems(items, hidden) {
|
|
1838
1951
|
if (!hidden || hidden.length === 0) return items;
|
|
@@ -1902,10 +2015,6 @@ var APP_POLLS_CHILDREN = [
|
|
|
1902
2015
|
{ label: "Command Center", icon: "grid", href: "https://polls.politogyvrm.com/" },
|
|
1903
2016
|
{ label: "New Poll", icon: "edit", href: "https://polls.politogyvrm.com/polls/new" }
|
|
1904
2017
|
];
|
|
1905
|
-
var APP_CTAS_CHILDREN = [
|
|
1906
|
-
{ label: "CTAs", icon: "list", href: "https://ctas.politogyvrm.com/" },
|
|
1907
|
-
{ label: "Canvas", icon: "edit", href: "https://ctas.politogyvrm.com/?tab=canvas" }
|
|
1908
|
-
];
|
|
1909
2018
|
var APP_A2P_CHILDREN = [
|
|
1910
2019
|
{ label: "Dashboard", icon: "grid", path: "dashboard" },
|
|
1911
2020
|
{ label: "Compose", icon: "edit", path: "compose" },
|
|
@@ -1953,16 +2062,27 @@ function standardPolitogyNav(opts) {
|
|
|
1953
2062
|
return { label: c.label, icon: icon(c.icon), href: withOrg(withMode) };
|
|
1954
2063
|
});
|
|
1955
2064
|
};
|
|
2065
|
+
const accountRows = () => [
|
|
2066
|
+
{ kind: "section", label: "Account" },
|
|
2067
|
+
// My Profile is global — NOT org-suffixed (main-app ShellChromeBridge).
|
|
2068
|
+
{ label: "My profile", icon: icon("circleUser"), href: withOrg(abs("/my-profile")) },
|
|
2069
|
+
{
|
|
2070
|
+
label: "Organization settings",
|
|
2071
|
+
icon: icon("settings"),
|
|
2072
|
+
href: withOrg(abs("/organization-settings")),
|
|
2073
|
+
children: branches(ORG_SETTINGS_CHILDREN)
|
|
2074
|
+
}
|
|
2075
|
+
];
|
|
1956
2076
|
const buildRelationship = () => {
|
|
1957
2077
|
const contacts = opts.contactsItem ? {
|
|
1958
2078
|
label: "Contacts",
|
|
1959
|
-
icon: icon("
|
|
2079
|
+
icon: icon("usersRound"),
|
|
1960
2080
|
href: opts.contactsItem.href,
|
|
1961
2081
|
children: opts.contactsItem.children,
|
|
1962
2082
|
badge: opts.contactsItem.count ?? void 0
|
|
1963
2083
|
} : {
|
|
1964
2084
|
label: "Contacts",
|
|
1965
|
-
icon: icon("
|
|
2085
|
+
icon: icon("usersRound"),
|
|
1966
2086
|
href: withOrg(`${CONTACTS_APP}/`),
|
|
1967
2087
|
children: APP_CONTACTS_CHILDREN.map((c) => ({
|
|
1968
2088
|
label: c.label,
|
|
@@ -1972,7 +2092,7 @@ function standardPolitogyNav(opts) {
|
|
|
1972
2092
|
};
|
|
1973
2093
|
return [
|
|
1974
2094
|
{ kind: "section", label: "Relationship" },
|
|
1975
|
-
{ label: "Dashboard", icon: icon("
|
|
2095
|
+
{ label: "Dashboard", icon: icon("layoutDashboard"), href: withOrg(abs("/relationship/dashboard")) },
|
|
1976
2096
|
contacts,
|
|
1977
2097
|
{
|
|
1978
2098
|
label: "Email broadcast",
|
|
@@ -1995,40 +2115,20 @@ function standardPolitogyNav(opts) {
|
|
|
1995
2115
|
},
|
|
1996
2116
|
{ kind: "section", label: "Collect" },
|
|
1997
2117
|
// Carries no top-level href in VRM core (parent row only toggles).
|
|
1998
|
-
{ label: "Calls to action", icon: icon("
|
|
2118
|
+
{ label: "Calls to action", icon: icon("mousePointerClick"), children: leaves(CTA_CHILDREN) },
|
|
1999
2119
|
{
|
|
2000
2120
|
label: "Forms",
|
|
2001
|
-
icon: icon("
|
|
2121
|
+
icon: icon("fileText"),
|
|
2002
2122
|
href: withOrg("https://forms.politogyvrm.com/"),
|
|
2003
2123
|
children: APP_FORMS_CHILDREN.map((c) => ({ label: c.label, icon: icon(c.icon), href: withOrg(c.href) }))
|
|
2004
2124
|
},
|
|
2005
2125
|
{
|
|
2006
2126
|
label: "Surveys",
|
|
2007
|
-
icon: icon("
|
|
2127
|
+
icon: icon("clipboardList"),
|
|
2008
2128
|
href: withOrg("https://surveys.politogyvrm.com/surveys"),
|
|
2009
2129
|
children: APP_SURVEYS_CHILDREN.map((c) => ({ label: c.label, icon: icon(c.icon), href: withOrg(c.href) }))
|
|
2010
2130
|
},
|
|
2011
|
-
|
|
2012
|
-
label: "Polls",
|
|
2013
|
-
icon: icon("barChart"),
|
|
2014
|
-
href: withOrg("https://polls.politogyvrm.com/"),
|
|
2015
|
-
children: APP_POLLS_CHILDREN.map((c) => ({ label: c.label, icon: icon(c.icon), href: withOrg(c.href) }))
|
|
2016
|
-
},
|
|
2017
|
-
{
|
|
2018
|
-
label: "CTAs",
|
|
2019
|
-
icon: icon("layout"),
|
|
2020
|
-
href: withOrg("https://ctas.politogyvrm.com/"),
|
|
2021
|
-
children: APP_CTAS_CHILDREN.map((c) => ({ label: c.label, icon: icon(c.icon), href: withOrg(c.href) }))
|
|
2022
|
-
},
|
|
2023
|
-
{ kind: "section", label: "Account" },
|
|
2024
|
-
// My Profile is global — NOT org-suffixed (main-app ShellChromeBridge).
|
|
2025
|
-
{ label: "My profile", icon: icon("user"), href: withOrg(abs("/my-profile")) },
|
|
2026
|
-
{
|
|
2027
|
-
label: "Organization settings",
|
|
2028
|
-
icon: icon("settings"),
|
|
2029
|
-
href: withOrg(abs("/organization-settings")),
|
|
2030
|
-
children: branches(ORG_SETTINGS_CHILDREN)
|
|
2031
|
-
}
|
|
2131
|
+
...accountRows()
|
|
2032
2132
|
];
|
|
2033
2133
|
};
|
|
2034
2134
|
const buildCampaign = () => {
|
|
@@ -2037,40 +2137,57 @@ function standardPolitogyNav(opts) {
|
|
|
2037
2137
|
...opts.campaignAvailability
|
|
2038
2138
|
};
|
|
2039
2139
|
const rows = [
|
|
2040
|
-
|
|
2041
|
-
|
|
2140
|
+
// Left-Navigation §9.2: Race data -> Research -> GOTV -> Account.
|
|
2141
|
+
// Battleground is the Campaign landing page; there is no Campaign
|
|
2142
|
+
// Dashboard row, and Voter Contact and Tribes have no row.
|
|
2143
|
+
{ kind: "section", label: "Race data" },
|
|
2144
|
+
{ label: "Battleground", icon: icon("crosshair"), href: withOrg(abs("/campaign/battleground")) },
|
|
2145
|
+
{ label: "District data", icon: icon("landmark"), href: withOrg(abs("/campaign/districts")) },
|
|
2146
|
+
{ kind: "section", label: "Research" },
|
|
2042
2147
|
{
|
|
2043
|
-
label: "
|
|
2044
|
-
icon: icon("
|
|
2045
|
-
href: withOrg(
|
|
2046
|
-
children:
|
|
2047
|
-
flag: "
|
|
2148
|
+
label: "Polling",
|
|
2149
|
+
icon: icon("chartNoAxes"),
|
|
2150
|
+
href: withOrg(POLLS_ORIGIN),
|
|
2151
|
+
children: APP_POLLS_CHILDREN.map((c) => ({ label: c.label, icon: icon(c.icon), href: withOrg(c.href) })),
|
|
2152
|
+
flag: "polling"
|
|
2153
|
+
},
|
|
2154
|
+
{ kind: "section", label: "GOTV" },
|
|
2155
|
+
{
|
|
2156
|
+
label: "Field canvassing",
|
|
2157
|
+
icon: icon("doorOpen"),
|
|
2158
|
+
href: withOrg(CANVASS_ORIGIN),
|
|
2159
|
+
children: appLeaves(CANVASS_ORIGIN, APP_CANVASS_CHILDREN),
|
|
2160
|
+
flag: "canvass"
|
|
2048
2161
|
},
|
|
2049
2162
|
{
|
|
2050
|
-
label: "Phone
|
|
2163
|
+
label: "Phone banking",
|
|
2051
2164
|
icon: icon("phone"),
|
|
2052
2165
|
href: withOrg(PHONEBANK_ORIGIN),
|
|
2053
2166
|
children: appLeaves(PHONEBANK_ORIGIN, APP_PHONEBANK_CHILDREN),
|
|
2054
2167
|
flag: "phonebank"
|
|
2055
2168
|
},
|
|
2056
2169
|
{
|
|
2057
|
-
label: "
|
|
2058
|
-
icon: icon("
|
|
2059
|
-
href: withOrg(
|
|
2060
|
-
children: appLeaves(
|
|
2061
|
-
flag: "
|
|
2170
|
+
label: "A2P texting",
|
|
2171
|
+
icon: icon("messageSquare"),
|
|
2172
|
+
href: withOrg(A2P_ORIGIN),
|
|
2173
|
+
children: appLeaves(A2P_ORIGIN, APP_A2P_CHILDREN),
|
|
2174
|
+
flag: "a2p"
|
|
2062
2175
|
},
|
|
2063
2176
|
{
|
|
2064
|
-
label: "Sign
|
|
2065
|
-
icon: icon("
|
|
2177
|
+
label: "Sign mapping",
|
|
2178
|
+
icon: icon("signpost"),
|
|
2066
2179
|
href: withOrg(SIGNS_ORIGIN),
|
|
2067
2180
|
children: appLeaves(SIGNS_ORIGIN, APP_SIGNS_CHILDREN),
|
|
2068
2181
|
flag: "signs"
|
|
2069
2182
|
},
|
|
2070
|
-
|
|
2071
|
-
{ label: "Polling Engine", icon: icon("barChart"), href: withOrg(POLLS_ORIGIN), flag: "polling" }
|
|
2183
|
+
...accountRows()
|
|
2072
2184
|
];
|
|
2073
|
-
|
|
2185
|
+
const kept = rows.filter((r) => !r.flag || avail[r.flag]).map(({ flag: _flag, ...item }) => item);
|
|
2186
|
+
return kept.filter((item, idx) => {
|
|
2187
|
+
if (item.kind !== "section") return true;
|
|
2188
|
+
const next = kept[idx + 1];
|
|
2189
|
+
return !!next && next.kind !== "section";
|
|
2190
|
+
});
|
|
2074
2191
|
};
|
|
2075
2192
|
const buildPetition = () => [
|
|
2076
2193
|
opts.petitionsItem ? {
|
|
@@ -2150,6 +2267,24 @@ function envChipClasses(label) {
|
|
|
2150
2267
|
return "bg-[rgba(107,114,128,0.16)] text-[#6b7280]";
|
|
2151
2268
|
}
|
|
2152
2269
|
var ORG_PILL_DEFAULT = "var(--color-accent)";
|
|
2270
|
+
var RailCollapsibleContext = react.createContext(false);
|
|
2271
|
+
function useRailCollapse() {
|
|
2272
|
+
const collapsible = react.useContext(RailCollapsibleContext);
|
|
2273
|
+
return (cls) => collapsible ? cls : "";
|
|
2274
|
+
}
|
|
2275
|
+
function OrgIconMark({ org, logoSrc }) {
|
|
2276
|
+
const rc = useRailCollapse();
|
|
2277
|
+
const src = resolveOrgLogoUrl(org.iconUrl) ?? logoSrc;
|
|
2278
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
2279
|
+
"span",
|
|
2280
|
+
{
|
|
2281
|
+
"aria-hidden": true,
|
|
2282
|
+
"data-rail-org-mark": "",
|
|
2283
|
+
className: `hidden h-8 w-8 shrink-0 items-center justify-center overflow-hidden rounded-[5px] bg-[#FFFFFF] text-[11px] font-bold text-neutral-800 ${rc("max-md:flex")}`,
|
|
2284
|
+
children: src ? /* @__PURE__ */ jsxRuntime.jsx("img", { src, alt: "", className: "max-h-full max-w-full object-contain" }) : (org.name ?? "Org").slice(0, 2).toUpperCase()
|
|
2285
|
+
}
|
|
2286
|
+
);
|
|
2287
|
+
}
|
|
2153
2288
|
function NavSidebar({
|
|
2154
2289
|
pathname,
|
|
2155
2290
|
brand,
|
|
@@ -2159,9 +2294,13 @@ function NavSidebar({
|
|
|
2159
2294
|
footer,
|
|
2160
2295
|
linkComponent,
|
|
2161
2296
|
open,
|
|
2162
|
-
onClose
|
|
2297
|
+
onClose,
|
|
2298
|
+
onOpen,
|
|
2299
|
+
onNavigate
|
|
2163
2300
|
}) {
|
|
2164
2301
|
const Link = linkComponent ?? DefaultLink;
|
|
2302
|
+
const collapsible = !open;
|
|
2303
|
+
const rc = (cls) => collapsible ? cls : "";
|
|
2165
2304
|
const asideRef = react.useRef(null);
|
|
2166
2305
|
const closeButtonRef = react.useRef(null);
|
|
2167
2306
|
const previouslyFocusedRef = react.useRef(null);
|
|
@@ -2228,12 +2367,12 @@ function NavSidebar({
|
|
|
2228
2367
|
setOpenGroup(activeGroupKey);
|
|
2229
2368
|
}, [activeGroupKey]);
|
|
2230
2369
|
const toggleGroup = (key) => setOpenGroup((prev) => prev === key ? null : key);
|
|
2231
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2370
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(RailCollapsibleContext.Provider, { value: collapsible, children: [
|
|
2232
2371
|
open ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
2233
2372
|
"div",
|
|
2234
2373
|
{
|
|
2235
2374
|
"aria-hidden": true,
|
|
2236
|
-
className: "fixed inset-0 z-40 bg-black/40
|
|
2375
|
+
className: "fixed inset-0 z-40 bg-black/40 md:hidden",
|
|
2237
2376
|
onClick: onClose
|
|
2238
2377
|
}
|
|
2239
2378
|
) : null,
|
|
@@ -2246,13 +2385,15 @@ function NavSidebar({
|
|
|
2246
2385
|
"aria-modal": open ? "true" : void 0,
|
|
2247
2386
|
"aria-label": open ? "Navigation" : void 0,
|
|
2248
2387
|
className: clsx__default.default(
|
|
2249
|
-
"fixed inset-y-0 left-0
|
|
2250
|
-
|
|
2388
|
+
"fixed inset-y-0 left-0 flex flex-col border-r border-[color:var(--sidebar-line,var(--line))] bg-[color:var(--sidebar-bg,var(--nav-surface))]",
|
|
2389
|
+
// Never hidden: the 64px icon rail below `md`, the full rail from
|
|
2390
|
+
// `md` up, and the full rail as a drawer when expanded below `md`.
|
|
2391
|
+
open ? "z-50 w-[var(--sidebar-width,236px)]" : "z-30 w-[var(--sidebar-collapsed-width,64px)] md:w-[var(--sidebar-width,236px)]"
|
|
2251
2392
|
),
|
|
2252
2393
|
style: { fontFamily: 'var(--font-family, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif)' },
|
|
2253
2394
|
onKeyDown: trapTab,
|
|
2254
2395
|
onClick: (e) => {
|
|
2255
|
-
if (open && e.target.closest("a[href]")) onClose?.();
|
|
2396
|
+
if (open && e.target.closest("a[href]")) (onNavigate ?? onClose)?.();
|
|
2256
2397
|
},
|
|
2257
2398
|
children: [
|
|
2258
2399
|
open ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -2261,37 +2402,75 @@ function NavSidebar({
|
|
|
2261
2402
|
type: "button",
|
|
2262
2403
|
ref: closeButtonRef,
|
|
2263
2404
|
onClick: onClose,
|
|
2264
|
-
"aria-label": "
|
|
2265
|
-
className: "absolute right-3 top-3 flex h-8 w-8 items-center justify-center rounded-full text-[color:var(--muted)] transition hover:bg-[color:var(--panel-elevated)] hover:text-[color:var(--foreground)]
|
|
2405
|
+
"aria-label": "Collapse navigation",
|
|
2406
|
+
className: "absolute right-3 top-3 flex h-8 w-8 items-center justify-center rounded-full text-[color:var(--muted)] transition hover:bg-[color:var(--panel-elevated)] hover:text-[color:var(--foreground)] md:hidden",
|
|
2266
2407
|
children: /* @__PURE__ */ jsxRuntime.jsx(CloseIcon, {})
|
|
2267
2408
|
}
|
|
2268
2409
|
) : null,
|
|
2269
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className:
|
|
2270
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2410
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: `flex flex-shrink-0 flex-col gap-[14px] border-b border-[color:var(--sidebar-line,var(--line))] px-[18px] py-4 ${rc("max-md:items-center max-md:px-[10px]")}`, children: [
|
|
2411
|
+
onOpen ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
2412
|
+
"button",
|
|
2413
|
+
{
|
|
2414
|
+
type: "button",
|
|
2415
|
+
onClick: onOpen,
|
|
2416
|
+
"aria-label": "Expand navigation",
|
|
2417
|
+
"aria-expanded": open ?? false,
|
|
2418
|
+
"data-rail-toggle": "expand",
|
|
2419
|
+
className: `hidden h-8 w-8 items-center justify-center rounded-lg ${rc("max-md:flex")}`,
|
|
2420
|
+
children: brand.logoSquareSrc ? /* @__PURE__ */ jsxRuntime.jsx("img", { src: brand.logoSquareSrc, alt: "", draggable: false, className: "h-8 w-8 object-contain" }) : brand.logoPending ? /* @__PURE__ */ jsxRuntime.jsx("span", { "aria-hidden": true, className: "block h-8 w-8" }) : /* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex h-8 w-8 items-center justify-center rounded-xl bg-[color:var(--color-accent)] text-sm font-black text-[#FFFFFF]", children: brand.badgeLabel })
|
|
2421
|
+
}
|
|
2422
|
+
) : null,
|
|
2423
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
2271
2424
|
Link,
|
|
2272
2425
|
{
|
|
2273
2426
|
href: brand.homeHref ?? "/",
|
|
2274
|
-
|
|
2275
|
-
|
|
2276
|
-
|
|
2277
|
-
|
|
2278
|
-
|
|
2279
|
-
|
|
2280
|
-
|
|
2281
|
-
|
|
2282
|
-
|
|
2283
|
-
|
|
2284
|
-
|
|
2285
|
-
|
|
2286
|
-
|
|
2287
|
-
|
|
2427
|
+
"aria-label": brand.logoAlt ?? brand.title,
|
|
2428
|
+
className: `flex items-center gap-2.5 ${rc("max-md:justify-center")} ${onOpen ? rc("max-md:hidden") : ""}`,
|
|
2429
|
+
children: [
|
|
2430
|
+
brand.logoSquareSrc ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
2431
|
+
"img",
|
|
2432
|
+
{
|
|
2433
|
+
src: brand.logoSquareSrc,
|
|
2434
|
+
alt: "",
|
|
2435
|
+
draggable: false,
|
|
2436
|
+
"data-rail-logo": "square",
|
|
2437
|
+
className: `hidden h-8 w-8 object-contain ${rc("max-md:block")}`
|
|
2438
|
+
}
|
|
2439
|
+
) : brand.logoPending ? /* @__PURE__ */ jsxRuntime.jsx("span", { "aria-hidden": true, className: `hidden h-8 w-8 ${rc("max-md:block")}` }) : null,
|
|
2440
|
+
brand.logoSrc ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
2441
|
+
"img",
|
|
2442
|
+
{
|
|
2443
|
+
src: brand.logoSrc,
|
|
2444
|
+
alt: brand.logoAlt ?? brand.title,
|
|
2445
|
+
draggable: false,
|
|
2446
|
+
"data-rail-logo": "horizontal",
|
|
2447
|
+
className: `h-[var(--sidebar-brand-logo-height,24px)] w-auto object-contain ${rc("max-md:hidden")}`
|
|
2448
|
+
}
|
|
2449
|
+
) : brand.logoPending ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
2450
|
+
"span",
|
|
2451
|
+
{
|
|
2452
|
+
"aria-hidden": true,
|
|
2453
|
+
className: `block h-[var(--sidebar-brand-logo-height,24px)] ${rc("max-md:hidden")}`
|
|
2454
|
+
}
|
|
2455
|
+
) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
2456
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2457
|
+
"span",
|
|
2458
|
+
{
|
|
2459
|
+
className: `flex h-9 w-9 items-center justify-center rounded-xl bg-[color:var(--color-accent)] text-base font-black text-[#FFFFFF] shadow-sm ${brand.logoSquareSrc ? rc("max-md:hidden") : ""}`,
|
|
2460
|
+
children: brand.badgeLabel
|
|
2461
|
+
}
|
|
2462
|
+
),
|
|
2463
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: `flex flex-col leading-tight ${rc("max-md:hidden")}`, children: [
|
|
2464
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-base font-extrabold tracking-[-0.01em] text-[color:var(--color-accent)]", children: brand.title }),
|
|
2465
|
+
brand.subtitle ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[11px] font-semibold uppercase tracking-[0.16em] text-[color:var(--muted)]", children: brand.subtitle }) : null
|
|
2466
|
+
] })
|
|
2288
2467
|
] })
|
|
2289
|
-
]
|
|
2468
|
+
]
|
|
2290
2469
|
}
|
|
2291
2470
|
),
|
|
2292
|
-
org ? /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
2293
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className:
|
|
2294
|
-
org.loading ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className:
|
|
2471
|
+
org ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: rc("max-md:flex max-md:justify-center"), children: [
|
|
2472
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: `mb-[7px] flex items-center justify-between ${rc("max-md:hidden")}`, children: /* @__PURE__ */ jsxRuntime.jsx("p", { className: NAV_EYEBROW_CLASS, children: "Organization" }) }),
|
|
2473
|
+
org.loading ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `flex w-full items-center gap-2.5 rounded-md border border-[color:var(--line)] bg-[color:var(--panel-elevated)] px-2.5 py-2 shadow-sm ${rc("max-md:w-auto max-md:border-0 max-md:bg-transparent max-md:p-0 max-md:shadow-none")}`, children: [
|
|
2295
2474
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2296
2475
|
"span",
|
|
2297
2476
|
{
|
|
@@ -2303,7 +2482,7 @@ function NavSidebar({
|
|
|
2303
2482
|
"span",
|
|
2304
2483
|
{
|
|
2305
2484
|
"aria-hidden": true,
|
|
2306
|
-
className:
|
|
2485
|
+
className: `h-4 flex-1 animate-pulse rounded bg-[color:var(--panel)] ${rc("max-md:hidden")}`
|
|
2307
2486
|
}
|
|
2308
2487
|
),
|
|
2309
2488
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Loading organization" })
|
|
@@ -2312,9 +2491,11 @@ function NavSidebar({
|
|
|
2312
2491
|
"summary",
|
|
2313
2492
|
{
|
|
2314
2493
|
style: orgCardStyle,
|
|
2315
|
-
|
|
2494
|
+
title: org.name ?? void 0,
|
|
2495
|
+
className: `flex w-full cursor-pointer list-none flex-col overflow-hidden rounded-[5px] border border-[color:var(--sidebar-card-border,var(--sidebar-line,var(--line)))] bg-[color:var(--sidebar-card-bg,var(--panel-elevated))] text-left text-[color:var(--sidebar-text,var(--foreground))] transition hover:bg-[color:var(--sidebar-row-hover-bg,var(--panel))] [&::-webkit-details-marker]:hidden ${rc("max-md:w-auto max-md:items-center max-md:overflow-visible max-md:border-0 max-md:bg-transparent")}`,
|
|
2316
2496
|
children: [
|
|
2317
|
-
/* @__PURE__ */ jsxRuntime.
|
|
2497
|
+
/* @__PURE__ */ jsxRuntime.jsx(OrgIconMark, { org, logoSrc: orgLogoSrc }),
|
|
2498
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: `relative flex h-[var(--sidebar-org-band-height,48px)] w-full items-center justify-center bg-[#FFFFFF] px-3 py-[7px] ${rc("max-md:hidden")}`, children: [
|
|
2318
2499
|
orgLogoSrc ? /* @__PURE__ */ jsxRuntime.jsx("img", { src: orgLogoSrc, alt: "", className: "max-h-full max-w-[132px] object-contain" }) : org.canUploadLogo ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
2319
2500
|
"a",
|
|
2320
2501
|
{
|
|
@@ -2326,7 +2507,7 @@ function NavSidebar({
|
|
|
2326
2507
|
) : /* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate text-sm font-semibold text-neutral-800", children: org.name ?? "Organization" }),
|
|
2327
2508
|
/* @__PURE__ */ jsxRuntime.jsx("span", { "aria-hidden": true, className: "absolute inset-x-0 bottom-0 h-[3px]", style: { backgroundImage: orgGradient } })
|
|
2328
2509
|
] }),
|
|
2329
|
-
/* @__PURE__ */ jsxRuntime.jsxs("span", { className:
|
|
2510
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: `flex w-full min-w-0 items-center justify-between gap-[9px] px-[10px] py-2 ${rc("max-md:hidden")}`, children: [
|
|
2330
2511
|
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "flex min-w-0 flex-col", children: [
|
|
2331
2512
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2332
2513
|
"span",
|
|
@@ -2343,7 +2524,7 @@ function NavSidebar({
|
|
|
2343
2524
|
]
|
|
2344
2525
|
}
|
|
2345
2526
|
),
|
|
2346
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className:
|
|
2527
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: `absolute left-0 right-0 z-40 mt-1 max-h-[min(60vh,520px)] overflow-y-auto rounded-xl border border-[color:var(--line)] bg-[color:var(--panel-elevated)] py-1 shadow-[var(--shadow-soft)] ${rc("max-md:right-auto max-md:w-[236px]")}`, children: [
|
|
2347
2528
|
shouldShowOrgFilter(org.organizations.length) ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "sticky top-0 z-10 bg-[color:var(--panel-elevated)] px-2 pb-1 pt-1", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
2348
2529
|
"input",
|
|
2349
2530
|
{
|
|
@@ -2412,9 +2593,11 @@ function NavSidebar({
|
|
|
2412
2593
|
type: "button",
|
|
2413
2594
|
onClick: org.onClick,
|
|
2414
2595
|
style: orgCardStyle,
|
|
2415
|
-
|
|
2596
|
+
title: org.name ?? void 0,
|
|
2597
|
+
className: `flex w-full flex-col overflow-hidden rounded-[5px] border border-[color:var(--sidebar-card-border,var(--sidebar-line,var(--line)))] bg-[color:var(--sidebar-card-bg,var(--panel-elevated))] text-left text-[color:var(--sidebar-text,var(--foreground))] transition hover:bg-[color:var(--sidebar-row-hover-bg,var(--panel))] ${rc("max-md:w-auto max-md:items-center max-md:overflow-visible max-md:border-0 max-md:bg-transparent")}`,
|
|
2416
2598
|
children: [
|
|
2417
|
-
/* @__PURE__ */ jsxRuntime.
|
|
2599
|
+
/* @__PURE__ */ jsxRuntime.jsx(OrgIconMark, { org, logoSrc: orgLogoSrc }),
|
|
2600
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: `relative flex h-[var(--sidebar-org-band-height,48px)] w-full items-center justify-center bg-[#FFFFFF] px-3 py-[7px] ${rc("max-md:hidden")}`, children: [
|
|
2418
2601
|
orgLogoSrc ? /* @__PURE__ */ jsxRuntime.jsx("img", { src: orgLogoSrc, alt: "", className: "max-h-full max-w-[132px] object-contain" }) : org.canUploadLogo ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
2419
2602
|
"a",
|
|
2420
2603
|
{
|
|
@@ -2426,7 +2609,7 @@ function NavSidebar({
|
|
|
2426
2609
|
) : /* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate text-sm font-semibold text-neutral-800", children: org.name ?? "Organization" }),
|
|
2427
2610
|
/* @__PURE__ */ jsxRuntime.jsx("span", { "aria-hidden": true, className: "absolute inset-x-0 bottom-0 h-[3px]", style: { backgroundImage: orgGradient } })
|
|
2428
2611
|
] }),
|
|
2429
|
-
/* @__PURE__ */ jsxRuntime.jsxs("span", { className:
|
|
2612
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: `flex w-full min-w-0 items-center justify-between gap-[9px] px-[10px] py-2 ${rc("max-md:hidden")}`, children: [
|
|
2430
2613
|
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "flex min-w-0 flex-col", children: [
|
|
2431
2614
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2432
2615
|
"span",
|
|
@@ -2444,13 +2627,13 @@ function NavSidebar({
|
|
|
2444
2627
|
}
|
|
2445
2628
|
)
|
|
2446
2629
|
] }) : null,
|
|
2447
|
-
mode ? /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
2630
|
+
mode ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: rc("max-md:w-full"), children: [
|
|
2448
2631
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2449
2632
|
"div",
|
|
2450
2633
|
{
|
|
2451
2634
|
role: "radiogroup",
|
|
2452
2635
|
"aria-label": "Mode",
|
|
2453
|
-
className:
|
|
2636
|
+
className: `flex w-full items-center gap-1 rounded-lg border border-[color:var(--border-inverse,var(--sidebar-line,var(--line)))] bg-[color:var(--mode-track-bg,var(--panel-elevated))] p-[3px] ${rc("max-md:flex-col max-md:items-stretch")}`,
|
|
2454
2637
|
children: (mode.options && mode.options.length > 0 ? mode.options : [{ id: mode.label, label: mode.label, icon: ModeIcon }]).map(
|
|
2455
2638
|
(opt) => {
|
|
2456
2639
|
const selected = opt.label === mode.label;
|
|
@@ -2482,11 +2665,11 @@ function NavSidebar({
|
|
|
2482
2665
|
)
|
|
2483
2666
|
}
|
|
2484
2667
|
),
|
|
2485
|
-
/* @__PURE__ */ jsxRuntime.jsx("p", { className:
|
|
2668
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: `mt-1.5 text-left text-[11px] leading-[1.2] text-[color:var(--sidebar-caption,var(--sidebar-text-muted,var(--muted)))] ${rc("max-md:hidden")}`, children: modeCaption(mode.label) })
|
|
2486
2669
|
] }) : null
|
|
2487
2670
|
] }),
|
|
2488
2671
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-1 flex-col overflow-y-auto px-[10px] py-3", children: /* @__PURE__ */ jsxRuntime.jsxs("nav", { className: "flex flex-col gap-0.5", children: [
|
|
2489
|
-
nav.groupLabel ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: `${NAV_EYEBROW_CLASS} px-2 pb-1.5 pt-1`, children: nav.groupLabel }) : null,
|
|
2672
|
+
nav.groupLabel ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: `${NAV_EYEBROW_CLASS} px-2 pb-1.5 pt-1 ${rc("max-md:hidden")}`, children: nav.groupLabel }) : null,
|
|
2490
2673
|
nav.items.map((item, idx) => {
|
|
2491
2674
|
if (item.kind === "section") {
|
|
2492
2675
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -2552,7 +2735,7 @@ function NavSidebar({
|
|
|
2552
2735
|
);
|
|
2553
2736
|
})
|
|
2554
2737
|
] }) }),
|
|
2555
|
-
footer ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className:
|
|
2738
|
+
footer ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `relative flex-shrink-0 border-t border-[color:var(--sidebar-line,var(--line))] px-[14px] py-3 ${rc("max-md:px-[10px]")}`, children: [
|
|
2556
2739
|
footer.user ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
2557
2740
|
NavSidebarUserCard,
|
|
2558
2741
|
{
|
|
@@ -2561,7 +2744,7 @@ function NavSidebar({
|
|
|
2561
2744
|
onSignOut: footer.onSignOut
|
|
2562
2745
|
}
|
|
2563
2746
|
) : null,
|
|
2564
|
-
footer.links && footer.links.length > 0 ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: `flex flex-wrap items-center gap-[10px] text-[11px] leading-[1.2] ${footer.user ? "mt-3" : ""}`, children: footer.links.map((l) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
2747
|
+
footer.links && footer.links.length > 0 ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: `flex flex-wrap items-center gap-[10px] text-[11px] leading-[1.2] ${footer.user ? "mt-3" : ""} ${rc("max-md:hidden")}`, children: footer.links.map((l) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
2565
2748
|
"a",
|
|
2566
2749
|
{
|
|
2567
2750
|
href: safeHref(l.href),
|
|
@@ -2574,7 +2757,7 @@ function NavSidebar({
|
|
|
2574
2757
|
"div",
|
|
2575
2758
|
{
|
|
2576
2759
|
"data-shell-meta": true,
|
|
2577
|
-
className:
|
|
2760
|
+
className: `mt-1.5 flex flex-col items-start gap-0.5 font-[family-name:var(--font-plex-mono)] text-[10px] text-[color:var(--sidebar-meta-text,var(--sidebar-text))] ${rc("max-md:hidden")}`,
|
|
2578
2761
|
children: [
|
|
2579
2762
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1.5", children: [
|
|
2580
2763
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -2737,21 +2920,27 @@ function NavActiveRail() {
|
|
|
2737
2920
|
);
|
|
2738
2921
|
}
|
|
2739
2922
|
function NavRowBadge({ value }) {
|
|
2923
|
+
const rc = useRailCollapse();
|
|
2740
2924
|
if (value === void 0 || value === null || value === "") return null;
|
|
2741
|
-
return /* @__PURE__ */ jsxRuntime.jsx("span", { className:
|
|
2925
|
+
return /* @__PURE__ */ jsxRuntime.jsx("span", { className: `ml-auto shrink-0 font-[family-name:var(--font-plex-mono,ui-monospace,monospace)] text-[11px] font-semibold leading-none text-[color:var(--sidebar-caption,var(--sidebar-text-muted,var(--muted)))] ${rc("max-md:hidden")}`, children: value });
|
|
2742
2926
|
}
|
|
2743
2927
|
function NavSectionRow({
|
|
2744
2928
|
label,
|
|
2745
2929
|
first,
|
|
2746
2930
|
variant = "top"
|
|
2747
2931
|
}) {
|
|
2932
|
+
const rc = useRailCollapse();
|
|
2933
|
+
const collapsed = variant === "sub" ? "" : first ? rc("max-md:sr-only") : rc(
|
|
2934
|
+
"max-md:mx-2 max-md:my-2 max-md:h-px max-md:overflow-hidden max-md:bg-[color:var(--sidebar-line,var(--line))] max-md:p-0 max-md:text-transparent"
|
|
2935
|
+
);
|
|
2748
2936
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
2749
2937
|
"p",
|
|
2750
2938
|
{
|
|
2751
2939
|
className: [
|
|
2752
2940
|
NAV_EYEBROW_CLASS,
|
|
2753
2941
|
variant === "sub" ? "px-3 pb-0.5" : "px-2 pb-1.5 pt-1",
|
|
2754
|
-
first ? "" : variant === "sub" ? "mt-3" : "mt-[14px]"
|
|
2942
|
+
first ? "" : variant === "sub" ? "mt-3" : "mt-[14px]",
|
|
2943
|
+
collapsed
|
|
2755
2944
|
].join(" "),
|
|
2756
2945
|
children: label
|
|
2757
2946
|
}
|
|
@@ -2763,6 +2952,7 @@ function NavRow({
|
|
|
2763
2952
|
Link,
|
|
2764
2953
|
variant = "top"
|
|
2765
2954
|
}) {
|
|
2955
|
+
const rc = useRailCollapse();
|
|
2766
2956
|
const Icon = item.icon;
|
|
2767
2957
|
const isSub = variant === "sub";
|
|
2768
2958
|
const washActive = variant !== "top";
|
|
@@ -2788,9 +2978,12 @@ function NavRow({
|
|
|
2788
2978
|
}
|
|
2789
2979
|
) : null
|
|
2790
2980
|
) : /* @__PURE__ */ jsxRuntime.jsx(NavActiveRail, {}),
|
|
2791
|
-
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: `relative z-10 flex items-center ${rowPadding}`, children: [
|
|
2792
|
-
Icon ? /* @__PURE__ */ jsxRuntime.jsx(Icon, { size: iconSize, className: `shrink-0 ${iconClass}` }) :
|
|
2793
|
-
|
|
2981
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: `relative z-10 flex items-center ${rowPadding} ${rc("max-md:justify-center max-md:px-0")}`, children: [
|
|
2982
|
+
Icon ? /* @__PURE__ */ jsxRuntime.jsx(Icon, { size: iconSize, className: `shrink-0 ${iconClass}` }) : (
|
|
2983
|
+
// A row with no glyph still needs something on the icon rail.
|
|
2984
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { "aria-hidden": true, className: `hidden text-[11px] font-semibold uppercase ${rc("max-md:inline")}`, children: item.label.slice(0, 2) })
|
|
2985
|
+
),
|
|
2986
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: `min-w-0 flex-1 truncate ${rc("max-md:hidden")}`, children: item.label }),
|
|
2794
2987
|
/* @__PURE__ */ jsxRuntime.jsx(NavRowBadge, { value: item.badge })
|
|
2795
2988
|
] })
|
|
2796
2989
|
] });
|
|
@@ -2799,20 +2992,30 @@ function NavRow({
|
|
|
2799
2992
|
"span",
|
|
2800
2993
|
{
|
|
2801
2994
|
"aria-disabled": "true",
|
|
2802
|
-
title: item.disabledTitle,
|
|
2995
|
+
title: item.disabledTitle ?? item.label,
|
|
2803
2996
|
className: `${wrapperClasses} cursor-not-allowed opacity-50`,
|
|
2804
2997
|
children: inner
|
|
2805
2998
|
}
|
|
2806
2999
|
);
|
|
2807
3000
|
}
|
|
2808
3001
|
if (item.onClick && !item.href) {
|
|
2809
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
3002
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
3003
|
+
"button",
|
|
3004
|
+
{
|
|
3005
|
+
type: "button",
|
|
3006
|
+
onClick: item.onClick,
|
|
3007
|
+
title: item.label,
|
|
3008
|
+
className: `w-full text-left ${wrapperClasses}`,
|
|
3009
|
+
children: inner
|
|
3010
|
+
}
|
|
3011
|
+
);
|
|
2810
3012
|
}
|
|
2811
3013
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
2812
3014
|
Link,
|
|
2813
3015
|
{
|
|
2814
3016
|
href: item.href ?? "#",
|
|
2815
3017
|
"aria-current": active ? "page" : void 0,
|
|
3018
|
+
title: item.label,
|
|
2816
3019
|
className: wrapperClasses,
|
|
2817
3020
|
children: inner
|
|
2818
3021
|
}
|
|
@@ -2827,6 +3030,7 @@ function NavGroup({
|
|
|
2827
3030
|
activeFn,
|
|
2828
3031
|
Link
|
|
2829
3032
|
}) {
|
|
3033
|
+
const rc = useRailCollapse();
|
|
2830
3034
|
const Icon = item.icon;
|
|
2831
3035
|
const headerClasses = [
|
|
2832
3036
|
"group relative block w-full overflow-hidden text-left transition",
|
|
@@ -2843,19 +3047,21 @@ function NavGroup({
|
|
|
2843
3047
|
item.onClick?.();
|
|
2844
3048
|
},
|
|
2845
3049
|
"aria-expanded": open,
|
|
3050
|
+
title: item.label,
|
|
2846
3051
|
className: headerClasses,
|
|
2847
3052
|
children: [
|
|
2848
3053
|
active ? /* @__PURE__ */ jsxRuntime.jsx(NavActiveRail, {}) : null,
|
|
2849
|
-
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: `relative z-10 flex items-center ${NAV_TOP_ROW_CLASS(active)}`, children: [
|
|
3054
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: `relative z-10 flex items-center ${NAV_TOP_ROW_CLASS(active)} ${rc("max-md:justify-center max-md:px-0")}`, children: [
|
|
2850
3055
|
Icon ? /* @__PURE__ */ jsxRuntime.jsx(Icon, { size: NAV_TOP_ICON_SIZE, className: "shrink-0 text-current" }) : null,
|
|
2851
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className:
|
|
3056
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: `min-w-0 flex-1 truncate ${rc("max-md:hidden")}`, children: item.label }),
|
|
2852
3057
|
/* @__PURE__ */ jsxRuntime.jsx(NavRowBadge, { value: item.badge }),
|
|
2853
3058
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2854
3059
|
ChevronDown,
|
|
2855
3060
|
{
|
|
2856
3061
|
className: [
|
|
2857
3062
|
"shrink-0 opacity-80 transition-transform duration-200",
|
|
2858
|
-
open ? "rotate-180" : ""
|
|
3063
|
+
open ? "rotate-180" : "",
|
|
3064
|
+
rc("max-md:hidden")
|
|
2859
3065
|
].join(" ")
|
|
2860
3066
|
}
|
|
2861
3067
|
)
|
|
@@ -2863,7 +3069,7 @@ function NavGroup({
|
|
|
2863
3069
|
]
|
|
2864
3070
|
}
|
|
2865
3071
|
),
|
|
2866
|
-
open ? /* @__PURE__ */ jsxRuntime.jsx("div", { className:
|
|
3072
|
+
open ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: `overflow-hidden rounded-b-md bg-[color:var(--nav-submenu-bg)] p-1 ${rc("max-md:hidden")}`, children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-col gap-0.5", children: item.children.map((child, i) => {
|
|
2867
3073
|
if (child.kind === "section") {
|
|
2868
3074
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
2869
3075
|
NavSectionRow,
|
|
@@ -2993,7 +3199,7 @@ function NavTopBar({
|
|
|
2993
3199
|
const initials = (hasRealName ? rawName : user?.email ?? "P").slice(0, 2).toUpperCase();
|
|
2994
3200
|
const secondary = hasRealName ? user?.email || [user?.tier, user?.role].filter(Boolean).join(" \xB7 ") || "member" : [user?.tier, user?.role].filter(Boolean).join(" \xB7 ") || "member";
|
|
2995
3201
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "sticky top-0 z-20", children: [
|
|
2996
|
-
/* @__PURE__ */ jsxRuntime.jsxs("header", { className: "flex h-[var(--topbar-height,60px)] items-center justify-between gap-[14px] border-b border-[color:var(--line)] bg-[color:var(--panel)] px-[var(--topbar-padding-x,20px)]", children: [
|
|
3202
|
+
/* @__PURE__ */ jsxRuntime.jsxs("header", { className: "flex min-w-0 h-[var(--topbar-height,60px)] items-center justify-between gap-[8px] md:gap-[14px] border-b border-[color:var(--line)] bg-[color:var(--panel)] px-[var(--topbar-padding-x,20px)]", children: [
|
|
2997
3203
|
onOpenNav ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
2998
3204
|
"button",
|
|
2999
3205
|
{
|
|
@@ -3002,11 +3208,11 @@ function NavTopBar({
|
|
|
3002
3208
|
"aria-label": "Open menu",
|
|
3003
3209
|
"aria-expanded": navOpen ?? false,
|
|
3004
3210
|
"aria-controls": "politogy-nav-drawer",
|
|
3005
|
-
className: `${topBarIconButtonClass("default")} mr-1 shrink-0
|
|
3211
|
+
className: `${topBarIconButtonClass("default")} mr-1 shrink-0 md:hidden`,
|
|
3006
3212
|
children: /* @__PURE__ */ jsxRuntime.jsx(HamburgerIcon, {})
|
|
3007
3213
|
}
|
|
3008
3214
|
) : null,
|
|
3009
|
-
/* @__PURE__ */ jsxRuntime.jsxs("label", { className: "relative flex h-9 w-[320px] max-w-full shrink
|
|
3215
|
+
/* @__PURE__ */ jsxRuntime.jsxs("label", { className: "relative flex h-9 w-[320px] min-w-0 max-w-full shrink items-center md:shrink-0", children: [
|
|
3010
3216
|
/* @__PURE__ */ jsxRuntime.jsx(SearchIcon, { className: "pointer-events-none absolute left-[10px] h-[15px] w-[15px] text-[color:var(--muted)]" }),
|
|
3011
3217
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3012
3218
|
"input",
|
|
@@ -3026,13 +3232,13 @@ function NavTopBar({
|
|
|
3026
3232
|
"kbd",
|
|
3027
3233
|
{
|
|
3028
3234
|
"aria-hidden": true,
|
|
3029
|
-
className: "pointer-events-none absolute right-[10px] rounded-[3px] border border-[color:var(--line)] px-[5px] py-px font-[family-name:var(--font-plex-mono,ui-monospace,monospace)] text-[12px] leading-[1.2] text-[color:var(--muted)]",
|
|
3235
|
+
className: "pointer-events-none absolute right-[10px] hidden md:block rounded-[3px] border border-[color:var(--line)] px-[5px] py-px font-[family-name:var(--font-plex-mono,ui-monospace,monospace)] text-[12px] leading-[1.2] text-[color:var(--muted)]",
|
|
3030
3236
|
children: "/"
|
|
3031
3237
|
}
|
|
3032
3238
|
)
|
|
3033
3239
|
] }),
|
|
3034
3240
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative ml-auto flex shrink-0 items-center gap-[var(--topbar-icon-gap,8px)]", children: [
|
|
3035
|
-
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
3241
|
+
buildNotes ? /* @__PURE__ */ jsxRuntime.jsxs(
|
|
3036
3242
|
"button",
|
|
3037
3243
|
{
|
|
3038
3244
|
type: "button",
|
|
@@ -3043,7 +3249,7 @@ function NavTopBar({
|
|
|
3043
3249
|
buildNotes?.label ?? "Build notes"
|
|
3044
3250
|
]
|
|
3045
3251
|
}
|
|
3046
|
-
),
|
|
3252
|
+
) : null,
|
|
3047
3253
|
actionsList && actionsList.length > 0 ? actionsList.map((action) => /* @__PURE__ */ jsxRuntime.jsx(NavTopBarActionButton, { action }, action.key)) : null,
|
|
3048
3254
|
actions,
|
|
3049
3255
|
themeToggle,
|
|
@@ -3100,7 +3306,8 @@ function NavAccountMenuPanel({
|
|
|
3100
3306
|
onSignOut,
|
|
3101
3307
|
placement
|
|
3102
3308
|
}) {
|
|
3103
|
-
const
|
|
3309
|
+
const rc = useRailCollapse();
|
|
3310
|
+
const wrapper = placement === "above" ? rc("max-md:right-auto max-md:w-64") + " absolute bottom-full left-0 right-0 z-40 mb-2 flex max-h-[calc(100vh-5rem)] flex-col overflow-hidden rounded-xl border border-[color:var(--line)] bg-[color:var(--panel-elevated)] py-1 text-[color:var(--foreground)] shadow-[var(--shadow-soft)]" : "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)]";
|
|
3104
3311
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: wrapper, children: [
|
|
3105
3312
|
placement === "below" ? /* @__PURE__ */ jsxRuntime.jsx(TopBarPanelArrow, {}) : null,
|
|
3106
3313
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "min-h-0 flex-1 overflow-y-auto overscroll-contain", children: [
|
|
@@ -3252,19 +3459,20 @@ function NavSidebarUserCard({
|
|
|
3252
3459
|
const displayName = hasRealName ? rawName : user.email ?? "Signed in";
|
|
3253
3460
|
const initials = (hasRealName ? rawName : user.email ?? "P").slice(0, 2).toUpperCase();
|
|
3254
3461
|
const secondary = hasRealName ? user.email || [user.tier, user.role].filter(Boolean).join(" \xB7 ") || "member" : [user.tier, user.role].filter(Boolean).join(" \xB7 ") || "member";
|
|
3462
|
+
const rc = useRailCollapse();
|
|
3255
3463
|
return /* @__PURE__ */ jsxRuntime.jsxs("details", { "data-nav-details": true, className: "group/acct relative", children: [
|
|
3256
3464
|
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
3257
3465
|
"summary",
|
|
3258
3466
|
{
|
|
3259
3467
|
"aria-label": "My Account",
|
|
3260
|
-
className:
|
|
3468
|
+
className: `flex w-full cursor-pointer list-none items-center gap-[9px] rounded-[5px] px-1 py-1 text-left transition hover:bg-[color:var(--sidebar-row-hover-bg,var(--panel-elevated))] [&::-webkit-details-marker]:hidden ${rc("max-md:justify-center max-md:px-0")}`,
|
|
3261
3469
|
children: [
|
|
3262
3470
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex h-7 w-7 shrink-0 items-center justify-center overflow-hidden rounded-full bg-[color:var(--sidebar-avatar-bg,var(--color-accent))] text-[11px] font-bold text-[#FFFFFF]", children: user.avatarUrl || user.memojiUrl ? /* @__PURE__ */ jsxRuntime.jsx("img", { src: user.avatarUrl || user.memojiUrl, alt: "", className: "h-full w-full object-cover" }) : initials }),
|
|
3263
|
-
/* @__PURE__ */ jsxRuntime.jsxs("span", { className:
|
|
3471
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: `flex min-w-0 flex-1 flex-col ${rc("max-md:hidden")}`, children: [
|
|
3264
3472
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate text-[12px] font-semibold leading-[1.2] text-[color:var(--sidebar-text,var(--foreground))]", children: displayName }),
|
|
3265
3473
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate text-[11px] leading-[1.3] text-[color:var(--sidebar-caption,var(--sidebar-text-muted,var(--muted)))]", children: secondary })
|
|
3266
3474
|
] }),
|
|
3267
|
-
/* @__PURE__ */ jsxRuntime.jsx(ChevronDown, { size: 14, className:
|
|
3475
|
+
/* @__PURE__ */ jsxRuntime.jsx(ChevronDown, { size: 14, className: `shrink-0 rotate-180 text-[color:var(--sidebar-caption,var(--sidebar-text-muted,var(--muted)))] transition group-open/acct:rotate-0 ${rc("max-md:hidden")}` })
|
|
3268
3476
|
]
|
|
3269
3477
|
}
|
|
3270
3478
|
),
|
|
@@ -3525,10 +3733,29 @@ function NavAppShell({
|
|
|
3525
3733
|
children
|
|
3526
3734
|
}) {
|
|
3527
3735
|
useCloseNavDetailsOnOutsideClick();
|
|
3736
|
+
if (contentWrapper === "bare") {
|
|
3737
|
+
warnDeprecated(
|
|
3738
|
+
"contentWrapper",
|
|
3739
|
+
"`contentWrapper: 'bare'` is deprecated: the frame's <main> is fluid and apps must not emit their own page container. Remove the app's PageContainer and drop the prop."
|
|
3740
|
+
);
|
|
3741
|
+
}
|
|
3528
3742
|
const [navOpen, setNavOpen] = react.useState(false);
|
|
3743
|
+
const expandRail = () => {
|
|
3744
|
+
writeRailPreference("expanded");
|
|
3745
|
+
setNavOpen(true);
|
|
3746
|
+
};
|
|
3747
|
+
const collapseRail = () => {
|
|
3748
|
+
writeRailPreference("collapsed");
|
|
3749
|
+
setNavOpen(false);
|
|
3750
|
+
};
|
|
3529
3751
|
react.useEffect(() => {
|
|
3530
3752
|
setNavOpen(false);
|
|
3531
3753
|
}, [sidebar.pathname]);
|
|
3754
|
+
react.useEffect(() => {
|
|
3755
|
+
if (readRailPreference() !== "expanded") return;
|
|
3756
|
+
const narrow = typeof window !== "undefined" && typeof window.matchMedia === "function" ? window.matchMedia("(max-width: 767.98px)").matches : false;
|
|
3757
|
+
if (narrow) setNavOpen(true);
|
|
3758
|
+
}, []);
|
|
3532
3759
|
react.useEffect(() => {
|
|
3533
3760
|
if (!navOpen) return;
|
|
3534
3761
|
const previous = document.body.style.overflow;
|
|
@@ -3549,31 +3776,41 @@ function NavAppShell({
|
|
|
3549
3776
|
"data-politogy-mode": modeId,
|
|
3550
3777
|
className: "min-h-screen bg-[color:var(--background)] text-[color:var(--foreground)]",
|
|
3551
3778
|
children: [
|
|
3552
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3553
|
-
|
|
3779
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3780
|
+
NavSidebar,
|
|
3781
|
+
{
|
|
3782
|
+
...sidebar,
|
|
3783
|
+
footer: sidebarFooter,
|
|
3784
|
+
open: navOpen,
|
|
3785
|
+
onClose: collapseRail,
|
|
3786
|
+
onOpen: expandRail,
|
|
3787
|
+
onNavigate: () => setNavOpen(false)
|
|
3788
|
+
}
|
|
3789
|
+
),
|
|
3790
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pl-[var(--sidebar-collapsed-width,64px)] md:pl-[var(--sidebar-width,236px)]", children: [
|
|
3554
3791
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3555
3792
|
NavTopBar,
|
|
3556
3793
|
{
|
|
3557
3794
|
...topBar,
|
|
3558
|
-
accountMenu: topBar.accountMenu ?? (accountMenuPlacement === "sidebar" ? "sidebar" : "topbar")
|
|
3559
|
-
onOpenNav: () => setNavOpen(true),
|
|
3560
|
-
navOpen
|
|
3795
|
+
accountMenu: topBar.accountMenu ?? (accountMenuPlacement === "sidebar" ? "sidebar" : "topbar")
|
|
3561
3796
|
}
|
|
3562
3797
|
),
|
|
3563
3798
|
betaBanner ? /* @__PURE__ */ jsxRuntime.jsx(NavBetaBanner, { ...betaBanner }) : null,
|
|
3564
|
-
topBar.title ? /* @__PURE__ */ jsxRuntime.jsx("h1", { className: "px-
|
|
3799
|
+
topBar.title ? /* @__PURE__ */ jsxRuntime.jsx("h1", { className: "px-4 pt-7 text-xl font-semibold text-[color:var(--foreground)] md:px-6", children: topBar.title }) : null,
|
|
3565
3800
|
contentWrapper === "bare" ? /* @__PURE__ */ jsxRuntime.jsx("div", { "data-shell-content": "", className: topBar.title ? "mt-[22px]" : void 0, children }) : (
|
|
3566
|
-
//
|
|
3567
|
-
//
|
|
3568
|
-
// gutter
|
|
3569
|
-
//
|
|
3570
|
-
//
|
|
3801
|
+
// Brand guidelines "Content width is fluid" + "Content body
|
|
3802
|
+
// padding": `<main>` fills the space beside the rail with ONE
|
|
3803
|
+
// gutter — 24px, or 16px below `md`, horizontally and vertically —
|
|
3804
|
+
// and has no max-width and no centered container. Form and settings
|
|
3805
|
+
// pages constrain themselves with <FormColumn> (960px, left-aligned).
|
|
3806
|
+
// The shell owns the page background and the gutter; an app's own
|
|
3807
|
+
// cards are its own furniture and stay app-owned.
|
|
3571
3808
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3572
3809
|
"main",
|
|
3573
3810
|
{
|
|
3574
3811
|
"data-shell-content": "",
|
|
3575
|
-
className: `min-h-[calc(100vh-63px)] bg-[color:var(--chrome-page-bg,#F4F5F7)] px-6 ${topBar.title ? "
|
|
3576
|
-
children
|
|
3812
|
+
className: `min-h-[calc(100vh-63px)] bg-[color:var(--chrome-page-bg,#F4F5F7)] px-4 pb-4 md:px-6 md:pb-6 ${topBar.title ? "pt-[22px]" : "pt-4 md:pt-6"}`,
|
|
3813
|
+
children
|
|
3577
3814
|
}
|
|
3578
3815
|
)
|
|
3579
3816
|
)
|
|
@@ -3630,66 +3867,6 @@ function resolveActiveOrg(search) {
|
|
|
3630
3867
|
return readActiveOrgCookie();
|
|
3631
3868
|
}
|
|
3632
3869
|
|
|
3633
|
-
// src/nav-preference.ts
|
|
3634
|
-
var NAV_DISPLAY_STORAGE_KEY = "politogy_nav_display";
|
|
3635
|
-
var NAV_DISPLAY_COOKIE = "politogy_nav_display";
|
|
3636
|
-
var LEGACY_NAV_DISPLAY_KEY = "vrm.navDisplay";
|
|
3637
|
-
var NAV_DISPLAY_DEFAULT = "both";
|
|
3638
|
-
var VALID2 = ["menu", "tabs", "both"];
|
|
3639
|
-
function isNavDisplayPreference(v) {
|
|
3640
|
-
return typeof v === "string" && VALID2.includes(v);
|
|
3641
|
-
}
|
|
3642
|
-
function readNavDisplayCookie() {
|
|
3643
|
-
if (typeof document === "undefined") return null;
|
|
3644
|
-
try {
|
|
3645
|
-
const m = document.cookie.match(
|
|
3646
|
-
new RegExp(`(?:^|;\\s*)${NAV_DISPLAY_COOKIE}=([^;]+)`)
|
|
3647
|
-
);
|
|
3648
|
-
const v = m ? decodeURIComponent(m[1]) : null;
|
|
3649
|
-
return isNavDisplayPreference(v) ? v : null;
|
|
3650
|
-
} catch {
|
|
3651
|
-
return null;
|
|
3652
|
-
}
|
|
3653
|
-
}
|
|
3654
|
-
function writeNavDisplayCookie(pref) {
|
|
3655
|
-
if (typeof document === "undefined" || typeof window === "undefined") return;
|
|
3656
|
-
const host = window.location.hostname;
|
|
3657
|
-
const domainAttr = /(^|\.)politogyvrm\.com$/i.test(host) ? "; Domain=.politogyvrm.com" : "";
|
|
3658
|
-
const secure = window.location.protocol === "https:" ? "; Secure" : "";
|
|
3659
|
-
document.cookie = `${NAV_DISPLAY_COOKIE}=${encodeURIComponent(
|
|
3660
|
-
pref
|
|
3661
|
-
)}; Path=/; Max-Age=31536000; SameSite=Lax${domainAttr}${secure}`;
|
|
3662
|
-
}
|
|
3663
|
-
function readNavDisplayLocal() {
|
|
3664
|
-
if (typeof localStorage === "undefined") return null;
|
|
3665
|
-
try {
|
|
3666
|
-
const current = localStorage.getItem(NAV_DISPLAY_STORAGE_KEY);
|
|
3667
|
-
if (isNavDisplayPreference(current)) return current;
|
|
3668
|
-
const legacy = localStorage.getItem(LEGACY_NAV_DISPLAY_KEY);
|
|
3669
|
-
return isNavDisplayPreference(legacy) ? legacy : null;
|
|
3670
|
-
} catch {
|
|
3671
|
-
return null;
|
|
3672
|
-
}
|
|
3673
|
-
}
|
|
3674
|
-
function writeNavDisplayLocal(pref) {
|
|
3675
|
-
if (typeof localStorage === "undefined") return;
|
|
3676
|
-
try {
|
|
3677
|
-
localStorage.setItem(NAV_DISPLAY_STORAGE_KEY, pref);
|
|
3678
|
-
} catch {
|
|
3679
|
-
}
|
|
3680
|
-
}
|
|
3681
|
-
function resolveNavDisplay() {
|
|
3682
|
-
return readNavDisplayCookie() ?? readNavDisplayLocal() ?? NAV_DISPLAY_DEFAULT;
|
|
3683
|
-
}
|
|
3684
|
-
`(function(){try{
|
|
3685
|
-
var KEY=${JSON.stringify(NAV_DISPLAY_STORAGE_KEY)};
|
|
3686
|
-
var VALID=["menu","tabs","both"];
|
|
3687
|
-
function fromCookie(){try{var m=document.cookie.match(/(?:^|;\\s*)${NAV_DISPLAY_COOKIE}=([^;]+)/);return m?decodeURIComponent(m[1]):null;}catch(e){return null;}}
|
|
3688
|
-
var cookie=fromCookie();
|
|
3689
|
-
if(cookie&&VALID.indexOf(cookie)!==-1){var ls=null;try{ls=localStorage.getItem(KEY);}catch(e){}
|
|
3690
|
-
if(cookie!==ls){try{localStorage.setItem(KEY,cookie);}catch(e){}}}
|
|
3691
|
-
}catch(e){}})();`;
|
|
3692
|
-
|
|
3693
3870
|
// src/lib/breadcrumbs.ts
|
|
3694
3871
|
function deriveBreadcrumbs(items, pathname, opts) {
|
|
3695
3872
|
const search = opts?.search ?? (typeof window !== "undefined" ? window.location.search : "");
|
|
@@ -4228,13 +4405,54 @@ function LoadingScreen({
|
|
|
4228
4405
|
}
|
|
4229
4406
|
);
|
|
4230
4407
|
}
|
|
4408
|
+
function parseCssUrl(value) {
|
|
4409
|
+
if (!value) return null;
|
|
4410
|
+
const m = /^url\(\s*(['"]?)(.*?)\1\s*\)$/i.exec(value.trim());
|
|
4411
|
+
const url = m?.[2]?.trim();
|
|
4412
|
+
return url && /^https:\/\//i.test(url) ? url : null;
|
|
4413
|
+
}
|
|
4414
|
+
function readBrandAsset(kind) {
|
|
4415
|
+
if (typeof document === "undefined") return null;
|
|
4416
|
+
try {
|
|
4417
|
+
return parseCssUrl(
|
|
4418
|
+
window.getComputedStyle(document.documentElement).getPropertyValue(`--asset-${kind}`)
|
|
4419
|
+
);
|
|
4420
|
+
} catch {
|
|
4421
|
+
return null;
|
|
4422
|
+
}
|
|
4423
|
+
}
|
|
4424
|
+
var EMPTY = { logoHorizontal: null, logoSquare: null };
|
|
4425
|
+
var RETRY_MS = [0, 250, 1e3, 3e3];
|
|
4426
|
+
function useBrandAssets() {
|
|
4427
|
+
const [assets, setAssets] = react.useState(EMPTY);
|
|
4428
|
+
react.useEffect(() => {
|
|
4429
|
+
let done = false;
|
|
4430
|
+
const read = () => {
|
|
4431
|
+
if (done) return;
|
|
4432
|
+
const next = {
|
|
4433
|
+
logoHorizontal: readBrandAsset("logo-horizontal"),
|
|
4434
|
+
logoSquare: readBrandAsset("logo-square")
|
|
4435
|
+
};
|
|
4436
|
+
setAssets(
|
|
4437
|
+
(prev) => prev.logoHorizontal === next.logoHorizontal && prev.logoSquare === next.logoSquare ? prev : next
|
|
4438
|
+
);
|
|
4439
|
+
};
|
|
4440
|
+
const links = Array.from(
|
|
4441
|
+
document.querySelectorAll('link[rel="stylesheet"][href*="api/tokens"]')
|
|
4442
|
+
);
|
|
4443
|
+
links.forEach((l) => l.addEventListener("load", read));
|
|
4444
|
+
const timers = RETRY_MS.map((ms) => window.setTimeout(read, ms));
|
|
4445
|
+
read();
|
|
4446
|
+
return () => {
|
|
4447
|
+
done = true;
|
|
4448
|
+
links.forEach((l) => l.removeEventListener("load", read));
|
|
4449
|
+
timers.forEach((t) => window.clearTimeout(t));
|
|
4450
|
+
};
|
|
4451
|
+
}, []);
|
|
4452
|
+
return assets;
|
|
4453
|
+
}
|
|
4231
4454
|
var CORE_APP = "vrm";
|
|
4232
4455
|
var DEFAULT_SIGN_OUT_URL = "/auth/signout";
|
|
4233
|
-
var DEFAULT_BRAND_LOGO = "/brand/logos/relationship-mode-logo.png";
|
|
4234
|
-
var MODE_BRAND_LOGOS = {
|
|
4235
|
-
petition: "/brand/logos/petition-mode-logo.svg"
|
|
4236
|
-
};
|
|
4237
|
-
var modeBrandLogo = (mode) => mode && MODE_BRAND_LOGOS[mode] || DEFAULT_BRAND_LOGO;
|
|
4238
4456
|
var POLITOGY_APPS = {
|
|
4239
4457
|
vrm: { title: "Politogy VRM", origin: "https://app.politogyvrm.com", storagePrefix: "vrm" },
|
|
4240
4458
|
contacts: {
|
|
@@ -4252,13 +4470,12 @@ var POLITOGY_APPS = {
|
|
|
4252
4470
|
origin: "https://petition-mode.politogyvrm.com",
|
|
4253
4471
|
storagePrefix: "petitions",
|
|
4254
4472
|
mode: "petition",
|
|
4255
|
-
//
|
|
4256
|
-
//
|
|
4257
|
-
//
|
|
4258
|
-
//
|
|
4259
|
-
//
|
|
4260
|
-
|
|
4261
|
-
grants: ["contentWrapper", "breadcrumbs", "title"],
|
|
4473
|
+
// Its adjudication case is addressed per sheet and per line — a trail
|
|
4474
|
+
// derived from the nav tree reads "Dashboard › Adjudication" on every one
|
|
4475
|
+
// of those URLs and cannot name the record you are actually on. 'title'
|
|
4476
|
+
// for the same reason: its pages have real names ("Batches"), where the
|
|
4477
|
+
// registry can only say "Petitions".
|
|
4478
|
+
grants: ["breadcrumbs", "title"],
|
|
4262
4479
|
navShape: "flat",
|
|
4263
4480
|
beta: false
|
|
4264
4481
|
},
|
|
@@ -4350,6 +4567,19 @@ function FrameBody({
|
|
|
4350
4567
|
}) {
|
|
4351
4568
|
const meta = POLITOGY_APPS[app];
|
|
4352
4569
|
const chrome = useChromeState();
|
|
4570
|
+
const brandAssets = useBrandAssets();
|
|
4571
|
+
if (data?.frame?.contentWrapper !== void 0) {
|
|
4572
|
+
warnDeprecated(
|
|
4573
|
+
"frame.contentWrapper",
|
|
4574
|
+
"`data.frame.contentWrapper` is retired and ignored: the frame's <main> is fluid. Remove the app's own page container and drop the prop."
|
|
4575
|
+
);
|
|
4576
|
+
}
|
|
4577
|
+
if (data?.core?.brandLogoSrc !== void 0) {
|
|
4578
|
+
warnDeprecated(
|
|
4579
|
+
"core.brandLogoSrc",
|
|
4580
|
+
"`data.core.brandLogoSrc` is ignored: the rail logo is read at runtime from Brand `assets.logoHorizontal`."
|
|
4581
|
+
);
|
|
4582
|
+
}
|
|
4353
4583
|
const bootAppMode = meta.mode;
|
|
4354
4584
|
const bootOrgId = chrome?.orgId ?? null;
|
|
4355
4585
|
const [bootVisible, setBootVisible] = react.useState(true);
|
|
@@ -4488,7 +4718,11 @@ function FrameBody({
|
|
|
4488
4718
|
sidebar: {
|
|
4489
4719
|
pathname,
|
|
4490
4720
|
brand: {
|
|
4491
|
-
logoSrc:
|
|
4721
|
+
logoSrc: brandAssets.logoHorizontal ?? void 0,
|
|
4722
|
+
logoSquareSrc: brandAssets.logoSquare ?? void 0,
|
|
4723
|
+
// Reserve the logo's box while the token sheet loads; never draw a
|
|
4724
|
+
// stand-in.
|
|
4725
|
+
logoPending: true,
|
|
4492
4726
|
logoAlt: "Politogy",
|
|
4493
4727
|
badgeLabel: "P",
|
|
4494
4728
|
title: "Politogy"
|
|
@@ -4520,7 +4754,7 @@ function FrameBody({
|
|
|
4520
4754
|
},
|
|
4521
4755
|
betaBanner: meta.beta === true ? {} : void 0,
|
|
4522
4756
|
modeId: appMode,
|
|
4523
|
-
contentWrapper: core?.contentWrapper
|
|
4757
|
+
contentWrapper: core?.contentWrapper,
|
|
4524
4758
|
topBar: {
|
|
4525
4759
|
// Core's pages publish their own identity; every other app is one
|
|
4526
4760
|
// product surface and takes its registry title.
|
|
@@ -4541,10 +4775,7 @@ function FrameBody({
|
|
|
4541
4775
|
// search yet, so this stays decorative (`NavTopBarProps.search` — "an
|
|
4542
4776
|
// app that has not wired search yet still gets the correct chrome").
|
|
4543
4777
|
search: { placeholder: data?.searchPlaceholder ?? DEFAULT_SEARCH_PLACEHOLDER[app] ?? "Search" },
|
|
4544
|
-
//
|
|
4545
|
-
// group. The spec names the element and its position but not its
|
|
4546
|
-
// destination content; `onOpen` is left unset until that is defined.
|
|
4547
|
-
buildNotes: {},
|
|
4778
|
+
// No Build notes control (Reference/UI-Platform, decided 2026-10-03).
|
|
4548
4779
|
// The action cluster is IDENTICAL everywhere — core included. Page
|
|
4549
4780
|
// actions sit BEFORE it, never inside it, so the Alerts bell keeps its
|
|
4550
4781
|
// required position: farthest right, immediately before My Account.
|
|
@@ -4559,33 +4790,43 @@ function FrameBody({
|
|
|
4559
4790
|
] });
|
|
4560
4791
|
}
|
|
4561
4792
|
var standardNavIcons = {
|
|
4562
|
-
home:
|
|
4563
|
-
users:
|
|
4564
|
-
mail:
|
|
4565
|
-
messageSquare:
|
|
4566
|
-
layout:
|
|
4567
|
-
activity:
|
|
4568
|
-
lifeBuoy:
|
|
4569
|
-
grid:
|
|
4570
|
-
list:
|
|
4571
|
-
upload:
|
|
4572
|
-
edit:
|
|
4573
|
-
fileText:
|
|
4574
|
-
send:
|
|
4575
|
-
clock:
|
|
4576
|
-
user:
|
|
4577
|
-
barChart:
|
|
4578
|
-
briefcase:
|
|
4579
|
-
settings:
|
|
4580
|
-
creditCard:
|
|
4581
|
-
dollarSign:
|
|
4582
|
-
share:
|
|
4793
|
+
home: lu.LuHouse,
|
|
4794
|
+
users: lu.LuUsers,
|
|
4795
|
+
mail: lu.LuMail,
|
|
4796
|
+
messageSquare: lu.LuMessageSquare,
|
|
4797
|
+
layout: lu.LuLayoutDashboard,
|
|
4798
|
+
activity: lu.LuActivity,
|
|
4799
|
+
lifeBuoy: lu.LuLifeBuoy,
|
|
4800
|
+
grid: lu.LuLayoutGrid,
|
|
4801
|
+
list: lu.LuList,
|
|
4802
|
+
upload: lu.LuUpload,
|
|
4803
|
+
edit: lu.LuPencil,
|
|
4804
|
+
fileText: lu.LuFileText,
|
|
4805
|
+
send: lu.LuSend,
|
|
4806
|
+
clock: lu.LuClock,
|
|
4807
|
+
user: lu.LuUser,
|
|
4808
|
+
barChart: lu.LuChartColumn,
|
|
4809
|
+
briefcase: lu.LuBriefcase,
|
|
4810
|
+
settings: lu.LuSettings,
|
|
4811
|
+
creditCard: lu.LuCreditCard,
|
|
4812
|
+
dollarSign: lu.LuDollarSign,
|
|
4813
|
+
share: lu.LuShare2,
|
|
4583
4814
|
// Campaign / Petition mode slots.
|
|
4584
|
-
phone:
|
|
4585
|
-
map:
|
|
4586
|
-
mapPin:
|
|
4587
|
-
target:
|
|
4588
|
-
flag:
|
|
4815
|
+
phone: lu.LuPhone,
|
|
4816
|
+
map: lu.LuMap,
|
|
4817
|
+
mapPin: lu.LuMapPin,
|
|
4818
|
+
target: lu.LuTarget,
|
|
4819
|
+
flag: lu.LuFlag,
|
|
4820
|
+
layoutDashboard: lu.LuLayoutDashboard,
|
|
4821
|
+
usersRound: lu.LuUsersRound,
|
|
4822
|
+
mousePointerClick: lu.LuMousePointerClick,
|
|
4823
|
+
clipboardList: lu.LuClipboardList,
|
|
4824
|
+
circleUser: lu.LuCircleUser,
|
|
4825
|
+
crosshair: lu.LuCrosshair,
|
|
4826
|
+
landmark: lu.LuLandmark,
|
|
4827
|
+
chartNoAxes: lu.LuChartNoAxesColumn,
|
|
4828
|
+
doorOpen: lu.LuDoorOpen,
|
|
4829
|
+
signpost: lu.LuSignpost
|
|
4589
4830
|
};
|
|
4590
4831
|
var ORG_STORAGE_KEY = "vrm.activeOrg";
|
|
4591
4832
|
var MODE_STORAGE_KEY = "vrm.activeMode";
|
|
@@ -5012,14 +5253,14 @@ var MODE_DEFS = [
|
|
|
5012
5253
|
{
|
|
5013
5254
|
id: "relationship",
|
|
5014
5255
|
label: "Relationship Mode",
|
|
5015
|
-
icon:
|
|
5256
|
+
icon: lu.LuContactRound,
|
|
5016
5257
|
href: `${CORE_BASE_URL}/relationship/dashboard`,
|
|
5017
5258
|
orgQuery: true
|
|
5018
5259
|
},
|
|
5019
5260
|
{
|
|
5020
5261
|
id: "campaign",
|
|
5021
5262
|
label: "Campaign Mode",
|
|
5022
|
-
icon:
|
|
5263
|
+
icon: lu.LuMegaphone,
|
|
5023
5264
|
href: `${CORE_BASE_URL}/campaign/dashboard`,
|
|
5024
5265
|
orgQuery: true
|
|
5025
5266
|
},
|
|
@@ -5028,7 +5269,7 @@ var MODE_DEFS = [
|
|
|
5028
5269
|
// petitions repo deploys production to petition-mode.politogyvrm.com.
|
|
5029
5270
|
id: "petition",
|
|
5030
5271
|
label: "Petition Mode",
|
|
5031
|
-
icon:
|
|
5272
|
+
icon: lu.LuFilePenLine,
|
|
5032
5273
|
href: "https://petition-mode.politogyvrm.com/",
|
|
5033
5274
|
orgQuery: true
|
|
5034
5275
|
}
|