@the-portland-company/shell 0.95.0 → 0.96.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.
@@ -1,6 +1,6 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
2
  import { ReactNode } from 'react';
3
- import { S as StandardNavIconKey, k as NavIcon, N as NavItem, l as NavBreadcrumb, m as StandardNavMode, o as NavLinkComponent, p as NavChromeFetcher, q as NavMode, s as NavUserMenu, t as NavOrgOption, f as NotificationsAdapter, u as NavFooterLink, v as NavFooter, w as NavDisplayMode } from './index-AIzWNzl-.cjs';
3
+ import { S as StandardNavIconKey, o as NavIcon, N as NavItem, p as NavBreadcrumb, q as StandardNavMode, s as NavLinkComponent, t as NavChromeFetcher, u as NavMode, v as NavUserMenu, w as NavOrgOption, f as NotificationsAdapter, x as NavFooterLink, y as NavFooter, z as NavDisplayMode } from './index-3YFy4JHI.cjs';
4
4
  import './theme-preference.cjs';
5
5
  import './brand-favicon.cjs';
6
6
 
@@ -1,6 +1,6 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
2
  import { ReactNode } from 'react';
3
- import { S as StandardNavIconKey, k as NavIcon, N as NavItem, l as NavBreadcrumb, m as StandardNavMode, o as NavLinkComponent, p as NavChromeFetcher, q as NavMode, s as NavUserMenu, t as NavOrgOption, f as NotificationsAdapter, u as NavFooterLink, v as NavFooter, w as NavDisplayMode } from './index-Byjq0Whp.js';
3
+ import { S as StandardNavIconKey, o as NavIcon, N as NavItem, p as NavBreadcrumb, q as StandardNavMode, s as NavLinkComponent, t as NavChromeFetcher, u as NavMode, v as NavUserMenu, w as NavOrgOption, f as NotificationsAdapter, x as NavFooterLink, y as NavFooter, z as NavDisplayMode } from './index-CqHKy3vG.js';
4
4
  import './theme-preference.js';
5
5
  import './brand-favicon.js';
6
6
 
@@ -1,10 +1,10 @@
1
1
  "use client";
2
2
  import { broadcastLogout, watchLogout } from './chunk-LL6LSJAH.js';
3
3
  import { writeUrlState } from './chunk-GVQKZI5X.js';
4
- import { clearBetaBannerDismissal, standardPolitogyNav, standardNavIcons, isNavItemActive, NavAppShell } from './chunk-BA3GITRQ.js';
5
- export { standardNavIcons } from './chunk-BA3GITRQ.js';
4
+ import { clearBetaBannerDismissal, standardPolitogyNav, standardNavIcons, isNavItemActive, NavAppShell } from './chunk-QGNJLKT5.js';
5
+ export { standardNavIcons } from './chunk-QGNJLKT5.js';
6
6
  import { authBaseUrl, orgIdTail, settingsBaseUrl, ORG_ID_QUERY_PARAM, readOrgSelectorFromUrl, matchOrgSelector, syncOrgIdInUrl, isOrgId, switchActiveOrg, ACTIVE_ORG_QUERY_PARAM, writeActiveOrgCookie, resolveActiveOrg, readActiveOrgCookie } from './chunk-5LO5W7W5.js';
7
- import { warnDeprecated, NavChromeProvider, TopBarWidgetSlot, FuelAction, SpecOverlayAction, NotificationsAction, SupportAction, useChromeMe, useNavChromeDedupedFetch, useChromeOrgs, useNavChromeFetcher } from './chunk-JQ53VZO5.js';
7
+ import { warnDeprecated, NavChromeProvider, TopBarWidgetSlot, FuelAction, SpecOverlayAction, NotificationsAction, SupportAction, useChromeMe, useNavChromeDedupedFetch, useChromeOrgs, useNavChromeFetcher } from './chunk-5OTXPYZU.js';
8
8
  import './chunk-BHRVZPZ7.js';
9
9
  import { NAV_DISPLAY_DEFAULT, resolveNavDisplay, writeNavDisplayLocal, writeNavDisplayCookie, isNavDisplayPreference, NAV_DISPLAY_STORAGE_KEY, readNavDisplayCookie } from './chunk-7YVJ7HQG.js';
10
10
  import { useBrandAssets, BrandFavicon } from './chunk-BMR5WAWH.js';
@@ -1,9 +1,9 @@
1
1
  import { readThemeCookie, THEME_STORAGE_KEY, isThemePreference, applyThemePreference, readPendingThemeChoice, writeThemeCookie, clearPendingThemeChoice, markThemeChoicePending } from './chunk-BHRVZPZ7.js';
2
2
  import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
3
+ import { createContext, useState, useRef, useCallback, useEffect, useLayoutEffect, useContext, useMemo, useSyncExternalStore } from 'react';
4
+ import { createPortal } from 'react-dom';
3
5
  import clsx2 from 'clsx';
4
- import { createContext, useState, useEffect, useRef, useContext, useMemo, useCallback, useSyncExternalStore } from 'react';
5
6
  import { FiUser, FiSettings, FiMessageSquare, FiMail, FiInfo, FiSun, FiMoon, FiHelpCircle, FiLifeBuoy, FiAlertCircle, FiAlertTriangle, FiBell, FiGrid, FiZap, FiBatteryCharging, FiBattery } from 'react-icons/fi';
6
- import { createPortal } from 'react-dom';
7
7
  import { LuGitBranch, LuWorkflow, LuNetwork, LuHandshake, LuBriefcase, LuAward, LuBadgeCheck, LuSignpost, LuDoorOpen, LuTriangleAlert, LuInfo, LuCircleHelp, LuTrash2, LuArchive, LuRocket, LuZap, LuWrench, LuKanban, LuNewspaper, LuLandmark, LuVote, LuKey, LuLock, LuEye, LuPrinter, LuMic, LuVideo, LuImage, LuLink, LuGlobe, LuSearch, LuFilter, LuTag, LuHandHeart, LuHeart, LuStar, LuHouse, LuBell, LuMailOpen, LuMail, LuDollarSign, LuReceipt, LuWallet, LuCreditCard, LuPalette, LuBuilding2, LuShare2, LuInbox, LuSlidersHorizontal, LuSettings, LuFlaskConical, LuTarget, LuSparkles, LuPencil, LuSmartphone, LuHistory, LuRefreshCw, LuRotateCcw, LuCircleCheck, LuSquareCheck, LuVoicemail, LuRadio, LuNotebookPen, LuBookOpen, LuPhoneCall, LuPhone, LuShieldCheck, LuShield, LuMegaphone, LuTrendingUp, LuListTodo, LuListOrdered, LuListChecks, LuList, LuFolderLock, LuFolder, LuFiles, LuFile, LuFileText, LuSplit, LuGauge, LuSend, LuMessageCircle, LuMessageSquare, LuMessagesSquare, LuBot, LuRoute, LuScale, LuLayers, LuCalendar, LuClock, LuTimer, LuClipboardCheck, LuClipboardList, LuBrain, LuFootprints, LuMapPin, LuMap, LuCrosshair, LuLightbulb, LuChartNoAxesCombined, LuChartArea, LuChartBar, LuChartLine, LuChartColumn, LuChartPie, LuTable2, LuActivity, LuFlagTriangleRight, LuFlag, LuLibrary, LuCopy, LuDownload, LuUpload, LuSquareUser, LuUserCheck, LuUserPlus, LuUser, LuUsersRound, LuUsers, LuLayoutTemplate, LuLayoutGrid, LuLayoutList, LuLayoutDashboard } from 'react-icons/lu';
8
8
 
9
9
  function Card({
@@ -92,6 +92,258 @@ function AiCreditsState({
92
92
  )
93
93
  ] });
94
94
  }
95
+ var GAP = 4;
96
+ var EDGE = 8;
97
+ var closeOpenRowMenu = null;
98
+ var TRIGGER_STYLE = {
99
+ display: "inline-flex",
100
+ alignItems: "center",
101
+ justifyContent: "center",
102
+ width: 28,
103
+ height: 28,
104
+ borderRadius: 6,
105
+ border: "none",
106
+ background: "transparent",
107
+ color: "var(--color-text-muted, #6b7280)",
108
+ cursor: "pointer",
109
+ lineHeight: 1
110
+ };
111
+ var PANEL_STYLE = {
112
+ minWidth: 160,
113
+ padding: 4,
114
+ border: "1px solid var(--color-border, #e5e7eb)",
115
+ borderRadius: 8,
116
+ background: "var(--color-surface, #fff)",
117
+ boxShadow: "0 10px 24px rgba(15, 23, 42, 0.12)",
118
+ display: "flex",
119
+ flexDirection: "column",
120
+ textAlign: "left"
121
+ };
122
+ var ITEM_STYLE = {
123
+ display: "flex",
124
+ alignItems: "center",
125
+ gap: 8,
126
+ width: "100%",
127
+ padding: "6px 10px",
128
+ border: "none",
129
+ borderRadius: 6,
130
+ background: "transparent",
131
+ font: "inherit",
132
+ fontSize: 14,
133
+ color: "var(--color-text, #2F3136)",
134
+ textAlign: "left",
135
+ cursor: "pointer"
136
+ };
137
+ function rowMenuPosition(trigger, panel, viewport) {
138
+ const below = viewport.height - trigger.bottom - GAP - EDGE;
139
+ const above = trigger.top - GAP - EDGE;
140
+ const placement = panel.height > below && above > below ? "above" : "below";
141
+ const rawTop = placement === "above" ? trigger.top - GAP - panel.height : trigger.bottom + GAP;
142
+ const top = Math.max(EDGE, Math.min(rawTop, viewport.height - panel.height - EDGE));
143
+ const left = Math.max(EDGE, Math.min(trigger.right - panel.width, viewport.width - panel.width - EDGE));
144
+ return { top, left, placement };
145
+ }
146
+ function menuItems(panel) {
147
+ if (!panel) return [];
148
+ return Array.from(panel.querySelectorAll('[role="menuitem"]')).filter(
149
+ (el) => !el.disabled && el.getAttribute("aria-disabled") !== "true"
150
+ );
151
+ }
152
+ function RowMenu({
153
+ label = "More actions",
154
+ title,
155
+ icon,
156
+ children,
157
+ triggerClassName,
158
+ triggerStyle,
159
+ panelClassName,
160
+ panelStyle,
161
+ onOpenChange
162
+ }) {
163
+ const [open, setOpen] = useState(false);
164
+ const [pos, setPos] = useState(null);
165
+ const triggerRef = useRef(null);
166
+ const panelRef = useRef(null);
167
+ const focusFirstRef = useRef(false);
168
+ const onOpenChangeRef = useRef(onOpenChange);
169
+ onOpenChangeRef.current = onOpenChange;
170
+ const close = useCallback((restoreFocus = false) => {
171
+ setOpen(false);
172
+ if (restoreFocus) triggerRef.current?.focus();
173
+ }, []);
174
+ const place = useCallback(() => {
175
+ const t = triggerRef.current;
176
+ const p = panelRef.current;
177
+ if (!t || !p) return;
178
+ const r = t.getBoundingClientRect();
179
+ setPos(rowMenuPosition(
180
+ { top: r.top, bottom: r.bottom, right: r.right },
181
+ { width: p.offsetWidth, height: p.offsetHeight },
182
+ { width: window.innerWidth, height: window.innerHeight }
183
+ ));
184
+ }, []);
185
+ useEffect(() => {
186
+ onOpenChangeRef.current?.(open);
187
+ if (!open) {
188
+ setPos(null);
189
+ return;
190
+ }
191
+ const mine = () => setOpen(false);
192
+ if (closeOpenRowMenu && closeOpenRowMenu !== mine) closeOpenRowMenu();
193
+ closeOpenRowMenu = mine;
194
+ return () => {
195
+ if (closeOpenRowMenu === mine) closeOpenRowMenu = null;
196
+ };
197
+ }, [open]);
198
+ useLayoutEffect(() => {
199
+ if (!open) return;
200
+ place();
201
+ const p = panelRef.current;
202
+ if (!p || typeof ResizeObserver === "undefined") return;
203
+ const ro = new ResizeObserver(() => place());
204
+ ro.observe(p);
205
+ return () => ro.disconnect();
206
+ }, [open, place]);
207
+ useEffect(() => {
208
+ if (!open || !pos || !focusFirstRef.current) return;
209
+ focusFirstRef.current = false;
210
+ menuItems(panelRef.current)[0]?.focus();
211
+ }, [open, pos]);
212
+ useEffect(() => {
213
+ if (!open) return;
214
+ const inside = (n) => n instanceof Node && (!!triggerRef.current?.contains(n) || !!panelRef.current?.contains(n));
215
+ const onPointerDown = (e) => {
216
+ if (!inside(e.target)) close();
217
+ };
218
+ const onKey = (e) => {
219
+ if (e.key === "Escape") {
220
+ e.stopPropagation();
221
+ close(true);
222
+ }
223
+ };
224
+ const onScroll = (e) => {
225
+ if (!inside(e.target)) close();
226
+ };
227
+ const onResize = () => close();
228
+ document.addEventListener("pointerdown", onPointerDown, true);
229
+ document.addEventListener("keydown", onKey, true);
230
+ window.addEventListener("scroll", onScroll, true);
231
+ window.addEventListener("resize", onResize);
232
+ return () => {
233
+ document.removeEventListener("pointerdown", onPointerDown, true);
234
+ document.removeEventListener("keydown", onKey, true);
235
+ window.removeEventListener("scroll", onScroll, true);
236
+ window.removeEventListener("resize", onResize);
237
+ };
238
+ }, [open, close]);
239
+ function onTriggerKeyDown(e) {
240
+ if (e.key === "ArrowDown" || (e.key === "Enter" || e.key === " ") && !open) {
241
+ e.preventDefault();
242
+ focusFirstRef.current = true;
243
+ if (open) menuItems(panelRef.current)[0]?.focus();
244
+ else setOpen(true);
245
+ }
246
+ }
247
+ function onPanelKeyDown(e) {
248
+ e.stopPropagation();
249
+ if (e.key === "Tab") {
250
+ close();
251
+ return;
252
+ }
253
+ if (e.key !== "ArrowDown" && e.key !== "ArrowUp" && e.key !== "Home" && e.key !== "End") return;
254
+ const items = menuItems(panelRef.current);
255
+ if (items.length === 0) return;
256
+ e.preventDefault();
257
+ const at = items.indexOf(document.activeElement);
258
+ const next = e.key === "Home" ? 0 : e.key === "End" ? items.length - 1 : e.key === "ArrowDown" ? (at + 1) % items.length : (at - 1 + items.length) % items.length;
259
+ items[next]?.focus();
260
+ }
261
+ function onPanelClick(e) {
262
+ e.stopPropagation();
263
+ const item = e.target.closest?.('[role="menuitem"]');
264
+ if (!item || !panelRef.current?.contains(item)) return;
265
+ if (item.disabled || item.getAttribute("aria-disabled") === "true") return;
266
+ setTimeout(() => close(), 0);
267
+ }
268
+ const panel = open && typeof document !== "undefined" ? createPortal(
269
+ /* @__PURE__ */ jsx(
270
+ "div",
271
+ {
272
+ ref: panelRef,
273
+ role: "menu",
274
+ "aria-label": label,
275
+ "data-row-menu": "",
276
+ "data-placement": pos?.placement,
277
+ className: panelClassName,
278
+ onClick: onPanelClick,
279
+ onKeyDown: onPanelKeyDown,
280
+ style: {
281
+ ...panelClassName ? null : PANEL_STYLE,
282
+ ...panelStyle,
283
+ position: "fixed",
284
+ zIndex: 1e3,
285
+ top: pos?.top ?? 0,
286
+ left: pos?.left ?? 0,
287
+ right: "auto",
288
+ bottom: "auto",
289
+ margin: 0,
290
+ visibility: pos ? "visible" : "hidden"
291
+ },
292
+ children
293
+ }
294
+ ),
295
+ document.body
296
+ ) : null;
297
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
298
+ /* @__PURE__ */ jsx(
299
+ "button",
300
+ {
301
+ ref: triggerRef,
302
+ type: "button",
303
+ className: triggerClassName,
304
+ style: { ...triggerClassName ? null : TRIGGER_STYLE, ...triggerStyle },
305
+ "aria-label": label,
306
+ title,
307
+ "aria-haspopup": "menu",
308
+ "aria-expanded": open,
309
+ "data-open": open ? "" : void 0,
310
+ onClick: (e) => {
311
+ e.stopPropagation();
312
+ setOpen((v) => !v);
313
+ },
314
+ onKeyDown: onTriggerKeyDown,
315
+ children: icon ?? /* @__PURE__ */ jsx("span", { "aria-hidden": "true", children: "\u22EF" })
316
+ }
317
+ ),
318
+ panel
319
+ ] });
320
+ }
321
+ function RowMenuItem({
322
+ onSelect,
323
+ disabled,
324
+ danger,
325
+ className,
326
+ style,
327
+ children
328
+ }) {
329
+ return /* @__PURE__ */ jsx(
330
+ "button",
331
+ {
332
+ type: "button",
333
+ role: "menuitem",
334
+ className,
335
+ disabled,
336
+ onClick: onSelect,
337
+ style: {
338
+ ...className ? null : ITEM_STYLE,
339
+ ...className || !danger ? null : { color: "var(--color-red, #e63946)" },
340
+ ...className || !disabled ? null : { opacity: 0.5, cursor: "default" },
341
+ ...style
342
+ },
343
+ children
344
+ }
345
+ );
346
+ }
95
347
  function FormColumn({ children, className }) {
96
348
  return /* @__PURE__ */ jsx("div", { "data-shell-form-column": "", className: clsx2("w-full max-w-[960px]", className), children });
97
349
  }
@@ -2446,6 +2698,6 @@ function BreadcrumbBarView({
2446
2698
  );
2447
2699
  }
2448
2700
 
2449
- export { AI_CREDITS_STATE_TITLES, AiCreditsState, BreadcrumbBarView, CORE_APP_ORIGIN, CORE_BILLING_PATH, CREDIT_TYPE_LABELS, CREDIT_TYPE_ORDER, Card, CreditsAction, FormColumn, FuelAction, HeaderTabBar, KNOWN_TAB_GLYPHS, NAV_DISPLAY_OPTIONS, NavChromeProvider, NavDisplayAction, NavThemeControl, NotificationsAction, PageHeaderView, SPECS_ORIGIN, SpecOverlayAction, SpeculationRulesScript, SupportAction, TOPBAR_GLYPH_SIZE, TopBarCountBadge, TopBarPanelArrow, TopBarPopover, TopBarTooltip, TopBarWidgetSlot, aiCreditsWalletUrl, buildNavSpeculationRules, buildSpeculationRules, collectSiblingAppUrls, createCommsNotificationsAdapter, creditGaugeRatio, creditStateWord, creditTooltipLine, creditsAriaLabel, creditsIconState, emptyNotificationsFeed, normalizeNotificationsFeed, resolveBrandGlyph, resolveOrgLogoUrl, resolveTabGlyph, topBarIconButtonClass, useChromeMe, useChromeOrgs, useNavChromeDedupedFetch, useNavChromeFetcher, useThemePreference, useTopBarIconSlotGlyph, warnDeprecated };
2450
- //# sourceMappingURL=chunk-JQ53VZO5.js.map
2451
- //# sourceMappingURL=chunk-JQ53VZO5.js.map
2701
+ export { AI_CREDITS_STATE_TITLES, AiCreditsState, BreadcrumbBarView, CORE_APP_ORIGIN, CORE_BILLING_PATH, CREDIT_TYPE_LABELS, CREDIT_TYPE_ORDER, Card, CreditsAction, FormColumn, FuelAction, HeaderTabBar, KNOWN_TAB_GLYPHS, NAV_DISPLAY_OPTIONS, NavChromeProvider, NavDisplayAction, NavThemeControl, NotificationsAction, PageHeaderView, RowMenu, RowMenuItem, SPECS_ORIGIN, SpecOverlayAction, SpeculationRulesScript, SupportAction, TOPBAR_GLYPH_SIZE, TopBarCountBadge, TopBarPanelArrow, TopBarPopover, TopBarTooltip, TopBarWidgetSlot, aiCreditsWalletUrl, buildNavSpeculationRules, buildSpeculationRules, collectSiblingAppUrls, createCommsNotificationsAdapter, creditGaugeRatio, creditStateWord, creditTooltipLine, creditsAriaLabel, creditsIconState, emptyNotificationsFeed, normalizeNotificationsFeed, resolveBrandGlyph, resolveOrgLogoUrl, resolveTabGlyph, rowMenuPosition, topBarIconButtonClass, useChromeMe, useChromeOrgs, useNavChromeDedupedFetch, useNavChromeFetcher, useThemePreference, useTopBarIconSlotGlyph, warnDeprecated };
2702
+ //# sourceMappingURL=chunk-5OTXPYZU.js.map
2703
+ //# sourceMappingURL=chunk-5OTXPYZU.js.map