@the-portland-company/shell 0.2.1 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,8 +1,10 @@
1
- import { extendTheme, Tooltip, ChakraProvider, Menu, MenuButton, Box, HStack, Text, Portal, MenuList, MenuItem, Flex, MenuDivider, useDisclosure, useToast, IconButton, Modal, ModalOverlay, ModalContent, ModalHeader, ModalCloseButton, ModalBody, VStack, Textarea, ModalFooter, Button, useColorMode, Avatar, Heading, Spacer, Link as Link$1, Image } from '@chakra-ui/react';
1
+ import { extendTheme, Tooltip, ChakraProvider, useColorModeValue, Flex, Menu, MenuButton, HStack, Avatar, VStack, Text, Box, Portal, MenuList, MenuItem, MenuDivider, Badge, IconButton, Link as Link$1, Collapse, Skeleton, Button, Image, useDisclosure, useToast, Modal, ModalOverlay, ModalContent, ModalHeader, ModalCloseButton, ModalBody, Textarea, ModalFooter, useClipboard } from '@chakra-ui/react';
2
2
  import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
3
3
  import clsx2 from 'clsx';
4
- import { Link, useLocation } from 'react-router-dom';
4
+ import { Link, useLocation, useNavigate, NavLink } from 'react-router-dom';
5
5
  import { createContext, useEffect, useState, useMemo, useContext, useCallback } from 'react';
6
+ import { FiChevronDown, FiUser, FiRotateCcw, FiBriefcase, FiTrash2, FiUserPlus, FiLogOut, FiMenu, FiX } from 'react-icons/fi';
7
+ import { keyframes } from '@emotion/react';
6
8
 
7
9
  // src/theme/index.ts
8
10
 
@@ -1118,6 +1120,11 @@ var ShellMetaContext = createContext(null);
1118
1120
  var ShellOrgContext = createContext(null);
1119
1121
  var ShellLinkedAccountsContext = createContext(null);
1120
1122
  var ShellSupportProviderContext = createContext(null);
1123
+ var ShellModeContext = createContext(null);
1124
+ var ShellNavItemsContext = createContext(null);
1125
+ var ShellNavigationPreferenceContext = createContext(null);
1126
+ var ShellRoleContext = createContext(null);
1127
+ var ShellFooterContext = createContext(null);
1121
1128
  var ShellChromeContext = createContext(null);
1122
1129
  function toShellUser(session) {
1123
1130
  if (!session?.user) return null;
@@ -1186,7 +1193,7 @@ function ShellProvider({
1186
1193
  }),
1187
1194
  [devNotesMenu, myProfileHref]
1188
1195
  );
1189
- return /* @__PURE__ */ jsx(ShellAuthContext.Provider, { value, children: /* @__PURE__ */ jsx(ShellMetaContext.Provider, { value: meta, children: /* @__PURE__ */ jsx(ShellOrgContext.Provider, { value: organization ?? null, children: /* @__PURE__ */ jsx(ShellLinkedAccountsContext.Provider, { value: linkedAccounts ?? null, children: /* @__PURE__ */ jsx(ShellSupportProviderContext.Provider, { value: support ?? null, children: /* @__PURE__ */ jsx(ShellChromeContext.Provider, { value: chrome, children: /* @__PURE__ */ jsx(ChakraProvider, { theme: politogyTheme, children }) }) }) }) }) }) });
1196
+ return /* @__PURE__ */ jsx(ShellAuthContext.Provider, { value, children: /* @__PURE__ */ jsx(ShellMetaContext.Provider, { value: meta, children: /* @__PURE__ */ jsx(ShellOrgContext.Provider, { value: organization ?? null, children: /* @__PURE__ */ jsx(ShellLinkedAccountsContext.Provider, { value: linkedAccounts ?? null, children: /* @__PURE__ */ jsx(ShellSupportProviderContext.Provider, { value: support ?? null, children: /* @__PURE__ */ jsx(ShellModeContext.Provider, { value: null, children: /* @__PURE__ */ jsx(ShellNavItemsContext.Provider, { value: null, children: /* @__PURE__ */ jsx(ShellNavigationPreferenceContext.Provider, { value: null, children: /* @__PURE__ */ jsx(ShellRoleContext.Provider, { value: null, children: /* @__PURE__ */ jsx(ShellFooterContext.Provider, { value: null, children: /* @__PURE__ */ jsx(ShellChromeContext.Provider, { value: chrome, children: /* @__PURE__ */ jsx(ChakraProvider, { theme: politogyTheme, children }) }) }) }) }) }) }) }) }) }) }) });
1190
1197
  }
1191
1198
  function useShellAuth() {
1192
1199
  const ctx = useContext(ShellAuthContext);
@@ -1225,6 +1232,614 @@ function useShellChrome() {
1225
1232
  }
1226
1233
  return ctx;
1227
1234
  }
1235
+ function useShellMode() {
1236
+ return useContext(ShellModeContext);
1237
+ }
1238
+ function useShellNavItems() {
1239
+ return useContext(ShellNavItemsContext);
1240
+ }
1241
+ function useShellNavigationPreference() {
1242
+ return useContext(ShellNavigationPreferenceContext);
1243
+ }
1244
+ function useShellRole() {
1245
+ return useContext(ShellRoleContext);
1246
+ }
1247
+ function useShellFooter() {
1248
+ return useContext(ShellFooterContext);
1249
+ }
1250
+ function BrandLogo({ src, alt = "Brand", className, style }) {
1251
+ if (!src) return null;
1252
+ return /* @__PURE__ */ jsx(
1253
+ "img",
1254
+ {
1255
+ src,
1256
+ alt,
1257
+ className,
1258
+ style,
1259
+ draggable: false
1260
+ }
1261
+ );
1262
+ }
1263
+ var BrandLogo_default = BrandLogo;
1264
+
1265
+ // src/lib/userDisplay.ts
1266
+ function getUserDisplayName(user) {
1267
+ if (!user) return "User";
1268
+ return user.profile?.full_name || user.profile?.name || user.user_metadata?.full_name || user.user_metadata?.name || (typeof user.email === "string" ? user.email.split("@")[0] : "") || user.email || "User";
1269
+ }
1270
+ function avatarUrlFromUser(user) {
1271
+ if (!user) return void 0;
1272
+ const meta = user.raw.user_metadata;
1273
+ return meta?.avatar_url ?? void 0;
1274
+ }
1275
+ function UserMenu() {
1276
+ const { user, status, signOut } = useShellAuth();
1277
+ const {
1278
+ myProfileHref,
1279
+ organizationSettingsHref,
1280
+ showContinueOnboarding,
1281
+ onContinueOnboarding
1282
+ } = useShellChrome();
1283
+ const linked = useShellLinkedAccounts();
1284
+ const mode = useShellMode();
1285
+ const org = useShellOrganization();
1286
+ const role = useShellRole();
1287
+ const navigate = useNavigate();
1288
+ const menuListBg = useColorModeValue("white", "gray.900");
1289
+ const menuListBorderColor = useColorModeValue("gray.200", "gray.700");
1290
+ if (status !== "authenticated" || !user) return null;
1291
+ const displayName = getUserDisplayName(user.raw);
1292
+ const avatarUrl = avatarUrlFromUser(user);
1293
+ const modeConfig = mode?.getModeConfig() ?? null;
1294
+ const currentOrg = org?.currentOrg ?? null;
1295
+ const linkedAccounts = linked?.linkedAccounts ?? [];
1296
+ const activeRoleConfig = role?.activeRoleConfig ?? null;
1297
+ return /* @__PURE__ */ jsx(Flex, { alignItems: "center", children: /* @__PURE__ */ jsxs(Menu, { children: [
1298
+ /* @__PURE__ */ jsx(MenuButton, { py: 2, transition: "all 0.3s", _focus: { boxShadow: "none" }, children: /* @__PURE__ */ jsxs(HStack, { children: [
1299
+ /* @__PURE__ */ jsx(
1300
+ Avatar,
1301
+ {
1302
+ size: "sm",
1303
+ src: avatarUrl,
1304
+ name: displayName,
1305
+ bg: modeConfig?.primaryColor || "brand.500"
1306
+ }
1307
+ ),
1308
+ /* @__PURE__ */ jsxs(
1309
+ VStack,
1310
+ {
1311
+ display: { base: "none", md: "flex" },
1312
+ alignItems: "flex-start",
1313
+ spacing: "1px",
1314
+ ml: "2",
1315
+ children: [
1316
+ /* @__PURE__ */ jsx(HStack, { spacing: 2, children: /* @__PURE__ */ jsx(Text, { fontSize: "sm", children: displayName }) }),
1317
+ /* @__PURE__ */ jsx(Text, { fontSize: "xs", color: "gray.500", children: user.email })
1318
+ ]
1319
+ }
1320
+ ),
1321
+ /* @__PURE__ */ jsx(Box, { display: { base: "none", md: "flex" }, children: /* @__PURE__ */ jsx(FiChevronDown, {}) })
1322
+ ] }) }),
1323
+ /* @__PURE__ */ jsx(Portal, { children: /* @__PURE__ */ jsxs(MenuList, { bg: menuListBg, borderColor: menuListBorderColor, zIndex: 1500, children: [
1324
+ /* @__PURE__ */ jsx(MenuItem, { icon: /* @__PURE__ */ jsx(FiUser, {}), onClick: () => navigate(myProfileHref), children: "My Profile" }),
1325
+ showContinueOnboarding && /* @__PURE__ */ jsx(
1326
+ MenuItem,
1327
+ {
1328
+ icon: /* @__PURE__ */ jsx(FiRotateCcw, {}),
1329
+ onClick: () => {
1330
+ if (onContinueOnboarding) onContinueOnboarding();
1331
+ else window.dispatchEvent(new CustomEvent("app:continue-onboarding"));
1332
+ },
1333
+ children: "Continue Onboarding"
1334
+ }
1335
+ ),
1336
+ organizationSettingsHref && /* @__PURE__ */ jsx(
1337
+ MenuItem,
1338
+ {
1339
+ icon: /* @__PURE__ */ jsx(FiBriefcase, {}),
1340
+ onClick: () => navigate(organizationSettingsHref),
1341
+ children: "Organization Settings"
1342
+ }
1343
+ ),
1344
+ /* @__PURE__ */ jsx(MenuDivider, {}),
1345
+ /* @__PURE__ */ jsx(Text, { fontSize: "xs", color: "gray.500", px: 3, py: 1, fontWeight: "semibold", children: "ROLES & ORGANIZATIONS" }),
1346
+ /* @__PURE__ */ jsx(Box, { px: 3, py: 2, children: /* @__PURE__ */ jsxs(VStack, { align: "stretch", spacing: 1, children: [
1347
+ currentOrg && currentOrg.role && /* @__PURE__ */ jsxs(HStack, { children: [
1348
+ /* @__PURE__ */ jsx(
1349
+ Badge,
1350
+ {
1351
+ size: "sm",
1352
+ colorScheme: currentOrg.role === "owner" ? "purple" : currentOrg.role === "admin" ? "blue" : "gray",
1353
+ children: currentOrg.role.charAt(0).toUpperCase() + currentOrg.role.slice(1)
1354
+ }
1355
+ ),
1356
+ /* @__PURE__ */ jsxs(Text, { fontSize: "xs", color: "gray.500", children: [
1357
+ "in ",
1358
+ currentOrg.name
1359
+ ] })
1360
+ ] }),
1361
+ activeRoleConfig && !currentOrg?.role && /* @__PURE__ */ jsx(Badge, { colorScheme: activeRoleConfig.color, size: "sm", children: activeRoleConfig.name })
1362
+ ] }) }),
1363
+ linked && /* @__PURE__ */ jsxs(Fragment, { children: [
1364
+ /* @__PURE__ */ jsx(MenuDivider, {}),
1365
+ /* @__PURE__ */ jsx(Text, { fontSize: "xs", color: "gray.500", px: 3, py: 1, fontWeight: "semibold", children: "ACCOUNTS" }),
1366
+ /* @__PURE__ */ jsx(Box, { px: 3, py: 2, children: /* @__PURE__ */ jsxs(HStack, { spacing: 2, children: [
1367
+ /* @__PURE__ */ jsx(Avatar, { size: "xs", src: avatarUrl, name: displayName }),
1368
+ /* @__PURE__ */ jsxs(VStack, { align: "start", spacing: 0, flex: 1, children: [
1369
+ /* @__PURE__ */ jsx(Text, { fontSize: "xs", fontWeight: "medium", color: "brand.600", children: displayName }),
1370
+ /* @__PURE__ */ jsx(Text, { fontSize: "xs", color: "gray.400", children: "Active" })
1371
+ ] })
1372
+ ] }) }),
1373
+ linkedAccounts.map((account) => /* @__PURE__ */ jsx(
1374
+ MenuItem,
1375
+ {
1376
+ onClick: () => {
1377
+ void linked.switchToAccount(account.id);
1378
+ },
1379
+ _hover: { bg: "gray.50" },
1380
+ children: /* @__PURE__ */ jsxs(HStack, { spacing: 2, flex: 1, justify: "space-between", children: [
1381
+ /* @__PURE__ */ jsxs(HStack, { spacing: 2, children: [
1382
+ /* @__PURE__ */ jsx(
1383
+ Avatar,
1384
+ {
1385
+ size: "xs",
1386
+ src: account.avatarUrl ?? void 0,
1387
+ name: account.displayName ?? account.email
1388
+ }
1389
+ ),
1390
+ /* @__PURE__ */ jsxs(VStack, { align: "start", spacing: 0, children: [
1391
+ /* @__PURE__ */ jsx(Text, { fontSize: "xs", fontWeight: "medium", noOfLines: 1, children: account.displayName ?? account.email.split("@")[0] }),
1392
+ /* @__PURE__ */ jsx(Tooltip, { label: account.email, placement: "top", hasArrow: true, children: /* @__PURE__ */ jsx(
1393
+ Text,
1394
+ {
1395
+ fontSize: "xs",
1396
+ color: "gray.500",
1397
+ maxW: "120px",
1398
+ noOfLines: 1,
1399
+ textOverflow: "ellipsis",
1400
+ children: account.email
1401
+ }
1402
+ ) })
1403
+ ] })
1404
+ ] }),
1405
+ /* @__PURE__ */ jsx(
1406
+ IconButton,
1407
+ {
1408
+ as: "span",
1409
+ role: "button",
1410
+ tabIndex: 0,
1411
+ "aria-label": "Remove account",
1412
+ icon: /* @__PURE__ */ jsx(FiTrash2, {}),
1413
+ size: "xs",
1414
+ variant: "ghost",
1415
+ colorScheme: "red",
1416
+ onClick: (e) => {
1417
+ e.stopPropagation();
1418
+ linked.onRemoveAccount(account.id);
1419
+ }
1420
+ }
1421
+ )
1422
+ ] })
1423
+ },
1424
+ account.id
1425
+ )),
1426
+ /* @__PURE__ */ jsx(
1427
+ MenuItem,
1428
+ {
1429
+ icon: /* @__PURE__ */ jsx(FiUserPlus, {}),
1430
+ onClick: linked.onAddAccount,
1431
+ color: "brand.500",
1432
+ children: "Add Account"
1433
+ }
1434
+ )
1435
+ ] }),
1436
+ /* @__PURE__ */ jsx(MenuDivider, {}),
1437
+ /* @__PURE__ */ jsx(MenuItem, { icon: /* @__PURE__ */ jsx(FiLogOut, {}), onClick: () => void signOut(), children: "Sign out" })
1438
+ ] }) })
1439
+ ] }) });
1440
+ }
1441
+ function Header({ onOpen, id }) {
1442
+ const {
1443
+ pageTitle,
1444
+ breadcrumbs,
1445
+ headerActions,
1446
+ headerIconsSlot,
1447
+ brandLogoSrc,
1448
+ devNotesMenu
1449
+ } = useShellChrome();
1450
+ const mobileNavBg = useColorModeValue("white", "gray.900");
1451
+ const mobileNavBorderColor = useColorModeValue("gray.200", "gray.700");
1452
+ return /* @__PURE__ */ jsx(
1453
+ Flex,
1454
+ {
1455
+ id: id || "mobile-nav-container",
1456
+ ml: { base: 0, md: 60 },
1457
+ px: { base: 4, md: 4 },
1458
+ height: "20",
1459
+ alignItems: "center",
1460
+ bg: mobileNavBg,
1461
+ borderBottomWidth: "1px",
1462
+ borderBottomColor: mobileNavBorderColor,
1463
+ justifyContent: { base: "space-between", md: "space-between" },
1464
+ children: /* @__PURE__ */ jsxs(Flex, { w: "full", mx: "auto", align: "center", justify: "space-between", children: [
1465
+ /* @__PURE__ */ jsxs(HStack, { spacing: 4, minW: "0", children: [
1466
+ onOpen ? /* @__PURE__ */ jsx(
1467
+ IconButton,
1468
+ {
1469
+ display: { base: "flex", md: "none" },
1470
+ onClick: onOpen,
1471
+ variant: "outline",
1472
+ "aria-label": "open menu",
1473
+ icon: /* @__PURE__ */ jsx(FiMenu, {})
1474
+ }
1475
+ ) : null,
1476
+ brandLogoSrc ? /* @__PURE__ */ jsx(Box, { display: { base: "flex", md: "none" }, h: "32px", children: /* @__PURE__ */ jsx(BrandLogo_default, { src: brandLogoSrc, className: "h-full w-auto object-contain" }) }) : null,
1477
+ /* @__PURE__ */ jsxs(
1478
+ VStack,
1479
+ {
1480
+ align: "flex-start",
1481
+ spacing: 0,
1482
+ minW: "0",
1483
+ display: { base: "none", md: "flex" },
1484
+ children: [
1485
+ pageTitle ? /* @__PURE__ */ jsx(Text, { fontSize: "lg", fontWeight: "bold", noOfLines: 1, children: pageTitle }) : null,
1486
+ breadcrumbs && breadcrumbs.length > 0 ? /* @__PURE__ */ jsx(HStack, { spacing: 2, color: "gray.500", fontSize: "sm", mt: "1px", minW: "0", children: breadcrumbs.map((b, idx) => /* @__PURE__ */ jsxs(Box, { display: "inline-flex", alignItems: "center", minW: "0", children: [
1487
+ idx > 0 ? /* @__PURE__ */ jsx(Text, { color: "gray.400", mr: 2, children: " > " }) : null,
1488
+ b.href ? /* @__PURE__ */ jsx(
1489
+ Link$1,
1490
+ {
1491
+ as: NavLink,
1492
+ to: b.href,
1493
+ _hover: { textDecoration: "underline" },
1494
+ noOfLines: 1,
1495
+ children: b.label
1496
+ }
1497
+ ) : /* @__PURE__ */ jsx(Text, { noOfLines: 1, children: b.label })
1498
+ ] }, `${b.label}-${idx}`)) }) : null
1499
+ ]
1500
+ }
1501
+ )
1502
+ ] }),
1503
+ /* @__PURE__ */ jsxs(HStack, { spacing: 0, align: "center", children: [
1504
+ /* @__PURE__ */ jsxs(
1505
+ HStack,
1506
+ {
1507
+ spacing: 2,
1508
+ mr: "15px",
1509
+ color: "gray.600",
1510
+ sx: {
1511
+ '& button:not([role="menuitem"]):not([data-menu-item])': {
1512
+ width: "32px",
1513
+ height: "32px",
1514
+ minWidth: "32px",
1515
+ padding: 0
1516
+ },
1517
+ '& button:not([role="menuitem"]):not([data-menu-item]) svg': {
1518
+ width: "20px",
1519
+ height: "20px"
1520
+ }
1521
+ },
1522
+ children: [
1523
+ headerActions,
1524
+ headerIconsSlot,
1525
+ devNotesMenu
1526
+ ]
1527
+ }
1528
+ ),
1529
+ /* @__PURE__ */ jsx(UserMenu, {})
1530
+ ] })
1531
+ ] })
1532
+ }
1533
+ );
1534
+ }
1535
+ function BrandIcon({
1536
+ name,
1537
+ size,
1538
+ className,
1539
+ style,
1540
+ alt,
1541
+ basePath = "/brand/icons/"
1542
+ }) {
1543
+ const a11yLabel = alt ?? "";
1544
+ const isDecorative = a11yLabel === "";
1545
+ const inlineSize = size ? { width: size, height: size, ...style } : style;
1546
+ return /* @__PURE__ */ jsx(
1547
+ "img",
1548
+ {
1549
+ src: `${basePath}${name}.svg`,
1550
+ alt: a11yLabel,
1551
+ role: isDecorative ? "presentation" : void 0,
1552
+ "aria-hidden": isDecorative ? true : void 0,
1553
+ className,
1554
+ style: inlineSize,
1555
+ draggable: false
1556
+ }
1557
+ );
1558
+ }
1559
+ var BrandIcon_default = BrandIcon;
1560
+ var MODE_CAMPAIGN = "campaign";
1561
+ var MODE_PETITION = "petition";
1562
+ function NavItem({
1563
+ icon,
1564
+ brandIcon,
1565
+ children,
1566
+ href,
1567
+ action,
1568
+ subItems,
1569
+ badge,
1570
+ subLabel,
1571
+ isSubItem = false,
1572
+ isExpanded,
1573
+ onToggle,
1574
+ menuKey,
1575
+ isDisabled: navIsDisabled,
1576
+ disabled,
1577
+ ...rest
1578
+ }) {
1579
+ const location = useLocation();
1580
+ const navigate = useNavigate();
1581
+ const mode = useShellMode();
1582
+ const currentMode = mode?.currentMode ?? null;
1583
+ const modeConfig = mode?.getModeConfig() ?? null;
1584
+ const navPref = useShellNavigationPreference();
1585
+ const showSubMenu = navPref?.showSubMenu ?? true;
1586
+ const navHoverGradient = currentMode === MODE_CAMPAIGN ? "linear-gradient(90deg, #F2C94C 0%, #E63946 100%)" : currentMode === MODE_PETITION ? "linear-gradient(90deg, #F2C94C 0%, #007BFF 100%)" : "linear-gradient(90deg, #007BFF 0%, #E63946 100%)";
1587
+ const gradientSweepBefore = {
1588
+ content: '""',
1589
+ position: "absolute",
1590
+ top: 0,
1591
+ left: 0,
1592
+ bottom: 0,
1593
+ width: "0%",
1594
+ background: navHoverGradient,
1595
+ transition: "width 300ms ease",
1596
+ pointerEvents: "none",
1597
+ zIndex: 0
1598
+ };
1599
+ const isDisabled = Boolean(navIsDisabled || disabled);
1600
+ const effectiveHref = href || (Array.isArray(subItems) && subItems.length > 0 ? subItems[0].href : void 0);
1601
+ const effectivePathname = effectiveHref?.split("?")[0];
1602
+ const currentFullPath = location.pathname + location.search;
1603
+ const currentSearchParams = useMemo(
1604
+ () => new URLSearchParams(location.search),
1605
+ [location.search]
1606
+ );
1607
+ const matchesSubItem = (itemHref) => {
1608
+ if (itemHref === currentFullPath) return true;
1609
+ const itemPath = itemHref.split("?")[0];
1610
+ const itemSearch = itemHref.includes("?") ? itemHref.split("?")[1] : "";
1611
+ if (itemPath === location.pathname && !itemSearch) {
1612
+ return true;
1613
+ }
1614
+ if (location.pathname.startsWith(`${itemPath}/`)) {
1615
+ const itemSegments = itemPath.split("/").filter(Boolean);
1616
+ const locationSegments = location.pathname.split("/").filter(Boolean);
1617
+ const itemLastSegment = itemSegments[itemSegments.length - 1];
1618
+ const locationLastSegment = locationSegments[locationSegments.length - 1];
1619
+ if (itemLastSegment && itemLastSegment === locationLastSegment) {
1620
+ return true;
1621
+ }
1622
+ }
1623
+ if (itemPath === location.pathname && itemSearch) {
1624
+ const itemSearchParams = new URLSearchParams(itemSearch);
1625
+ const itemTab = itemSearchParams.get("tab") || itemSearchParams.get("view");
1626
+ if (!itemTab) return true;
1627
+ return itemTab === currentSearchParams.get("tab");
1628
+ }
1629
+ if (itemPath && !itemHref.includes("?") && itemPath !== effectivePathname) {
1630
+ const segment = itemPath.split("/").pop();
1631
+ if (segment && location.pathname.endsWith("/" + segment) && location.pathname.startsWith(itemPath.split("/").slice(0, -1).join("/"))) {
1632
+ return true;
1633
+ }
1634
+ }
1635
+ return false;
1636
+ };
1637
+ const isActive = isSubItem ? matchesSubItem(effectiveHref || "") : (() => {
1638
+ if (!effectivePathname) return false;
1639
+ if (location.pathname === effectivePathname) return true;
1640
+ if (location.pathname.startsWith(`${effectivePathname}/`)) return true;
1641
+ const dashboardOverviewMatch = effectivePathname.match(
1642
+ /^\/[^/]+\/[^/]*\/dashboard\/overview$/
1643
+ );
1644
+ if (dashboardOverviewMatch) {
1645
+ const dashboardRoot = effectivePathname.replace(/\/overview$/, "");
1646
+ return location.pathname === dashboardRoot || location.pathname.startsWith(`${dashboardRoot}/`) || location.pathname.startsWith(`${dashboardRoot}&`);
1647
+ }
1648
+ return effectivePathname !== `/${location.pathname.split("/")[1]}/dashboard` && location.pathname.startsWith(effectivePathname + "/");
1649
+ })();
1650
+ const hasSubItems = showSubMenu && Array.isArray(subItems) && subItems.length > 0;
1651
+ const hasActiveChild = hasSubItems && subItems.some((item) => matchesSubItem(item.href || ""));
1652
+ const isParentActive = isActive || hasActiveChild;
1653
+ const isSubMenuOpen = isExpanded !== void 0 ? isExpanded : hasSubItems && subItems.some((item) => matchesSubItem(item.href || ""));
1654
+ const expandedRowBg = isParentActive ? modeConfig?.primaryColor || "brand.500" : isSubMenuOpen ? "gray.100" : "transparent";
1655
+ const expandedRowTextColor = isParentActive ? "white" : isSubMenuOpen ? "gray.900" : "gray.600";
1656
+ const disabledRowBg = isSubItem ? "gray.50" : "transparent";
1657
+ const disabledRowTextColor = "gray.400";
1658
+ if (hasSubItems) {
1659
+ const headerProps = {
1660
+ align: "center",
1661
+ px: "4",
1662
+ py: "2.5",
1663
+ mx: "4",
1664
+ w: "auto",
1665
+ borderTopRadius: "lg",
1666
+ borderBottomRadius: isSubMenuOpen ? 0 : "lg",
1667
+ role: "group",
1668
+ cursor: isDisabled ? "not-allowed" : "pointer",
1669
+ opacity: 1,
1670
+ pointerEvents: isDisabled ? "none" : "auto",
1671
+ "data-nav-item-active": String(isParentActive),
1672
+ position: "relative",
1673
+ overflow: "hidden",
1674
+ bg: isDisabled ? disabledRowBg : expandedRowBg,
1675
+ color: isDisabled ? disabledRowTextColor : expandedRowTextColor,
1676
+ _before: isDisabled ? void 0 : gradientSweepBefore,
1677
+ _hover: {
1678
+ color: isDisabled ? disabledRowTextColor : "white",
1679
+ _before: isDisabled ? void 0 : { width: "100%" }
1680
+ },
1681
+ "aria-disabled": isDisabled ? "true" : "false",
1682
+ onClick: (e) => {
1683
+ if (isDisabled) return;
1684
+ if (effectiveHref) e.preventDefault();
1685
+ e.stopPropagation();
1686
+ onToggle?.(menuKey || null);
1687
+ }
1688
+ };
1689
+ return /* @__PURE__ */ jsxs(Box, { children: [
1690
+ /* @__PURE__ */ jsxs(Flex, { ...headerProps, ...rest, children: [
1691
+ brandIcon ? /* @__PURE__ */ jsx(
1692
+ Box,
1693
+ {
1694
+ mr: "4",
1695
+ display: "inline-flex",
1696
+ alignItems: "center",
1697
+ position: "relative",
1698
+ zIndex: 1,
1699
+ filter: isParentActive ? "brightness(0) invert(1)" : void 0,
1700
+ _groupHover: isDisabled ? void 0 : { filter: "brightness(0) invert(1)" },
1701
+ children: /* @__PURE__ */ jsx(BrandIcon_default, { name: brandIcon, size: 18 })
1702
+ }
1703
+ ) : icon ? /* @__PURE__ */ jsx(
1704
+ Box,
1705
+ {
1706
+ mr: "4",
1707
+ fontSize: "16",
1708
+ position: "relative",
1709
+ zIndex: 1,
1710
+ _groupHover: {
1711
+ color: isDisabled ? disabledRowTextColor : "white"
1712
+ },
1713
+ as: icon
1714
+ }
1715
+ ) : null,
1716
+ /* @__PURE__ */ jsx(Box, { flex: "1", position: "relative", zIndex: 1, children }),
1717
+ /* @__PURE__ */ jsx(
1718
+ Box,
1719
+ {
1720
+ as: FiChevronDown,
1721
+ position: "relative",
1722
+ zIndex: 1,
1723
+ transform: isSubMenuOpen ? "rotate(180deg)" : void 0,
1724
+ transition: "transform 0.2s"
1725
+ }
1726
+ )
1727
+ ] }),
1728
+ /* @__PURE__ */ jsx(Collapse, { in: isSubMenuOpen, animateOpacity: true, children: /* @__PURE__ */ jsx(
1729
+ Box,
1730
+ {
1731
+ px: "0",
1732
+ mx: "4",
1733
+ w: "auto",
1734
+ mb: "2",
1735
+ py: "1",
1736
+ borderTopRadius: 0,
1737
+ borderBottomRadius: "md",
1738
+ bg: isDisabled ? "gray.100" : "gray.200",
1739
+ children: subItems.map((item) => /* @__PURE__ */ jsx(
1740
+ NavItem,
1741
+ {
1742
+ icon: item.icon,
1743
+ brandIcon: item.brandIcon,
1744
+ href: item.href,
1745
+ isSubItem: true,
1746
+ isDisabled: item.disabled,
1747
+ subLabel: item.subLabel,
1748
+ children: item.name
1749
+ },
1750
+ item.name
1751
+ ))
1752
+ }
1753
+ ) })
1754
+ ] });
1755
+ }
1756
+ const handleClick = (e) => {
1757
+ if (isDisabled) {
1758
+ e.preventDefault();
1759
+ return;
1760
+ }
1761
+ if (action) {
1762
+ e.preventDefault();
1763
+ action();
1764
+ return;
1765
+ }
1766
+ if (effectiveHref) {
1767
+ e.preventDefault();
1768
+ navigate(effectiveHref);
1769
+ }
1770
+ };
1771
+ return /* @__PURE__ */ jsx(Box, { as: "a", href: effectiveHref || "#", onClick: handleClick, style: { textDecoration: "none" }, children: /* @__PURE__ */ jsxs(
1772
+ Flex,
1773
+ {
1774
+ align: "center",
1775
+ px: "4",
1776
+ py: "2.5",
1777
+ mx: isSubItem ? "0" : "4",
1778
+ w: isSubItem ? "full" : "auto",
1779
+ borderRadius: isSubItem ? "0" : "lg",
1780
+ role: "group",
1781
+ cursor: isDisabled ? "not-allowed" : "pointer",
1782
+ opacity: 1,
1783
+ pointerEvents: isDisabled ? "none" : "auto",
1784
+ "data-nav-item-active": String(isActive),
1785
+ position: "relative",
1786
+ overflow: "hidden",
1787
+ bg: isDisabled ? disabledRowBg : isActive ? isSubItem ? "gray.100" : modeConfig?.primaryColor || "brand.500" : "transparent",
1788
+ color: isDisabled ? disabledRowTextColor : isActive ? isSubItem ? modeConfig?.primaryColor || "brand.500" : "white" : "gray.600",
1789
+ _before: isDisabled ? void 0 : gradientSweepBefore,
1790
+ _hover: {
1791
+ color: isDisabled ? disabledRowTextColor : "white",
1792
+ _before: isDisabled ? void 0 : { width: "100%" }
1793
+ },
1794
+ "aria-disabled": isDisabled ? "true" : "false",
1795
+ onClick: handleClick,
1796
+ children: [
1797
+ brandIcon ? /* @__PURE__ */ jsx(
1798
+ Box,
1799
+ {
1800
+ mr: "4",
1801
+ display: "inline-flex",
1802
+ alignItems: "center",
1803
+ position: "relative",
1804
+ zIndex: 1,
1805
+ filter: isActive && !isSubItem ? "brightness(0) invert(1)" : void 0,
1806
+ _groupHover: isDisabled ? void 0 : { filter: "brightness(0) invert(1)" },
1807
+ children: /* @__PURE__ */ jsx(BrandIcon_default, { name: brandIcon, size: 18 })
1808
+ }
1809
+ ) : icon ? /* @__PURE__ */ jsx(
1810
+ Box,
1811
+ {
1812
+ mr: "4",
1813
+ fontSize: "16",
1814
+ position: "relative",
1815
+ zIndex: 1,
1816
+ _groupHover: {
1817
+ color: isDisabled ? disabledRowTextColor : "white"
1818
+ },
1819
+ as: icon
1820
+ }
1821
+ ) : null,
1822
+ /* @__PURE__ */ jsxs(Box, { flex: "1", position: "relative", zIndex: 1, children: [
1823
+ /* @__PURE__ */ jsx(Box, { children }),
1824
+ subLabel ? /* @__PURE__ */ jsx(
1825
+ Text,
1826
+ {
1827
+ mt: 0.5,
1828
+ fontSize: "10px",
1829
+ lineHeight: "1.3",
1830
+ color: isDisabled ? "gray.400" : "gray.400",
1831
+ children: subLabel
1832
+ }
1833
+ ) : null,
1834
+ badge && /* @__PURE__ */ jsx(Badge, { colorScheme: "orange", size: "xs", mt: 1, fontSize: "xs", display: "block", children: badge })
1835
+ ] })
1836
+ ]
1837
+ }
1838
+ ) });
1839
+ }
1840
+ var NavItem_default = NavItem;
1841
+
1842
+ // src/lib/orgColors.ts
1228
1843
  var HEX_COLOR_PATTERN = /^#(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{6})$/;
1229
1844
  function normalizeHexColor(value) {
1230
1845
  const trimmed = value?.trim();
@@ -1233,6 +1848,34 @@ function normalizeHexColor(value) {
1233
1848
  const [r, g, b] = trimmed.slice(1).split("");
1234
1849
  return `#${r}${r}${g}${g}${b}${b}`;
1235
1850
  }
1851
+ function hexToRgba(hex, alpha) {
1852
+ const normalized = normalizeHexColor(hex);
1853
+ if (!normalized) return null;
1854
+ const red = parseInt(normalized.slice(1, 3), 16);
1855
+ const green = parseInt(normalized.slice(3, 5), 16);
1856
+ const blue = parseInt(normalized.slice(5, 7), 16);
1857
+ return `rgba(${red}, ${green}, ${blue}, ${alpha})`;
1858
+ }
1859
+ function lightenHexColor(hex, amount) {
1860
+ const normalized = normalizeHexColor(hex);
1861
+ if (!normalized) return null;
1862
+ const clamp = (value) => Math.max(0, Math.min(255, Math.round(value)));
1863
+ const blend = (channel) => clamp(channel + (255 - channel) * amount);
1864
+ const red = parseInt(normalized.slice(1, 3), 16);
1865
+ const green = parseInt(normalized.slice(3, 5), 16);
1866
+ const blue = parseInt(normalized.slice(5, 7), 16);
1867
+ return `#${blend(red).toString(16).padStart(2, "0")}${blend(green).toString(16).padStart(2, "0")}${blend(blue).toString(16).padStart(2, "0")}`;
1868
+ }
1869
+ function getOrganizationBrandColor(organization) {
1870
+ if (!organization) return null;
1871
+ const direct = normalizeHexColor(organization.brandColor);
1872
+ if (direct) return direct;
1873
+ const brandColors = Array.isArray(organization.settings?.brand_colors) ? organization.settings?.brand_colors : [];
1874
+ const firstBrandColor = brandColors?.find(
1875
+ (entry) => typeof entry?.value === "string" && normalizeHexColor(entry.value)
1876
+ );
1877
+ return normalizeHexColor(firstBrandColor?.value ?? null);
1878
+ }
1236
1879
  function getOrganizationBadgeLetters(name) {
1237
1880
  const normalizedName = String(name || "").trim().replace(/[^a-zA-Z0-9\s]+/g, " ");
1238
1881
  const parts = normalizedName.split(/\s+/).filter(Boolean);
@@ -1267,60 +1910,465 @@ function OrgBadge({ name, logoUrl, brandColor, size }) {
1267
1910
  }
1268
1911
  );
1269
1912
  }
1270
- function OrgSelector() {
1913
+ function OrganizationIdCopy({ orgId }) {
1914
+ const { hasCopied, onCopy } = useClipboard(orgId);
1915
+ const copiedAnimation = keyframes`
1916
+ 0% { opacity: 0; transform: translateY(6px); }
1917
+ 20% { opacity: 1; transform: translateY(0); }
1918
+ 100% { opacity: 0; transform: translateY(-8px); }
1919
+ `;
1920
+ return /* @__PURE__ */ jsx(Tooltip, { label: orgId, placement: "top", hasArrow: true, children: /* @__PURE__ */ jsxs(
1921
+ Flex,
1922
+ {
1923
+ align: "center",
1924
+ cursor: "pointer",
1925
+ onClick: onCopy,
1926
+ _hover: { bg: "gray.100" },
1927
+ borderRadius: "md",
1928
+ px: 2,
1929
+ py: 1,
1930
+ position: "relative",
1931
+ transition: "all 0.2s",
1932
+ children: [
1933
+ /* @__PURE__ */ jsxs(Text, { fontSize: "xs", color: hasCopied ? "green.500" : "gray.600", fontWeight: "normal", children: [
1934
+ "...",
1935
+ orgId.slice(-8)
1936
+ ] }),
1937
+ hasCopied && /* @__PURE__ */ jsx(
1938
+ Box,
1939
+ {
1940
+ position: "absolute",
1941
+ bottom: "100%",
1942
+ mb: "6px",
1943
+ px: "2",
1944
+ py: "1",
1945
+ fontSize: "xs",
1946
+ bg: "gray.700",
1947
+ color: "white",
1948
+ borderRadius: "md",
1949
+ animation: `${copiedAnimation} 0.9s ease-out`,
1950
+ pointerEvents: "none",
1951
+ children: "Copied!"
1952
+ }
1953
+ )
1954
+ ]
1955
+ }
1956
+ ) });
1957
+ }
1958
+ function OrgPill() {
1271
1959
  const org = useShellOrganization();
1960
+ const { user } = useShellAuth();
1961
+ const currentOrg = org?.currentOrg ?? null;
1962
+ const organizations = org?.organizations ?? [];
1963
+ const switchOrganization = org?.switchOrganization;
1964
+ const loadingOrgs = org?.loadingOrgs ?? false;
1965
+ const unselectedOrganizations = useMemo(
1966
+ () => organizations.filter((o) => o.id !== currentOrg?.id),
1967
+ [organizations, currentOrg?.id]
1968
+ );
1969
+ const selectedOrgBrandColor = useMemo(
1970
+ () => currentOrg ? getOrganizationBrandColor(currentOrg) : null,
1971
+ [currentOrg]
1972
+ );
1973
+ const selectedOrgColor = selectedOrgBrandColor || "var(--mode-primary-color, #ea6a3a)";
1974
+ const selectedOrgMenuBg = selectedOrgBrandColor && lightenHexColor(selectedOrgBrandColor, 0.12) || "#4a4a4a";
1272
1975
  if (!org) return null;
1273
- const { currentOrg, organizations, switchOrganization, createOrgHref } = org;
1274
- const others = organizations.filter((o) => o.id !== currentOrg?.id);
1275
- return /* @__PURE__ */ jsxs(Menu, { placement: "bottom-start", children: [
1276
- /* @__PURE__ */ jsx(
1277
- MenuButton,
1278
- {
1279
- as: Box,
1280
- cursor: "pointer",
1281
- px: 2,
1282
- py: 1,
1283
- borderRadius: "md",
1284
- _hover: { bg: "gray.100" },
1285
- _active: { bg: "gray.200" },
1286
- "aria-label": "Switch organization",
1287
- children: /* @__PURE__ */ jsxs(HStack, { spacing: 2, align: "center", children: [
1288
- currentOrg ? /* @__PURE__ */ jsxs(Fragment, { children: [
1976
+ return /* @__PURE__ */ jsxs(Box, { mx: "4", mb: "3", children: [
1977
+ /* @__PURE__ */ jsxs(HStack, { justify: "space-between", align: "center", mb: "2", children: [
1978
+ /* @__PURE__ */ jsx(Text, { fontSize: "xs", color: "gray.500", fontWeight: "semibold", children: "ORGANIZATION" }),
1979
+ currentOrg?.id && currentOrg.id !== user?.id && /* @__PURE__ */ jsx(OrganizationIdCopy, { orgId: currentOrg.id })
1980
+ ] }),
1981
+ loadingOrgs && !currentOrg ? /* @__PURE__ */ jsx(Skeleton, { height: "32px", width: "full", borderRadius: "md" }) : /* @__PURE__ */ jsxs(Menu, { gutter: 0, children: [
1982
+ /* @__PURE__ */ jsx(
1983
+ MenuButton,
1984
+ {
1985
+ as: Button,
1986
+ rightIcon: /* @__PURE__ */ jsx(FiChevronDown, {}),
1987
+ size: "sm",
1988
+ width: "full",
1989
+ bg: currentOrg?.id ? selectedOrgColor : "gray.100",
1990
+ borderColor: currentOrg?.id ? selectedOrgColor : "gray.300",
1991
+ color: currentOrg?.id ? "white" : "gray.700",
1992
+ _hover: {
1993
+ bg: currentOrg?.id ? selectedOrgColor : "gray.200",
1994
+ color: currentOrg?.id ? "white" : "gray.900"
1995
+ },
1996
+ _active: {
1997
+ bg: currentOrg?.id ? selectedOrgColor : "gray.200",
1998
+ color: currentOrg?.id ? "white" : "gray.900"
1999
+ },
2000
+ _expanded: {
2001
+ bg: currentOrg?.id ? selectedOrgColor : "gray.200",
2002
+ color: currentOrg?.id ? "white" : "gray.900"
2003
+ },
2004
+ textAlign: "left",
2005
+ justifyContent: "flex-start",
2006
+ isDisabled: loadingOrgs && organizations.length === 0,
2007
+ sx: currentOrg?.id ? {
2008
+ color: "white",
2009
+ ".chakra-button__icon": { color: "white" }
2010
+ } : void 0,
2011
+ children: /* @__PURE__ */ jsxs(HStack, { spacing: "2.5", minW: 0, align: "center", children: [
1289
2012
  /* @__PURE__ */ jsx(
1290
2013
  OrgBadge,
1291
2014
  {
1292
- name: currentOrg.name,
1293
- logoUrl: currentOrg.logoUrl,
1294
- brandColor: currentOrg.brandColor,
1295
- size: "24px"
2015
+ name: currentOrg?.name,
2016
+ logoUrl: currentOrg?.logoUrl,
2017
+ brandColor: selectedOrgBrandColor,
2018
+ size: "28px"
1296
2019
  }
1297
2020
  ),
1298
- /* @__PURE__ */ jsx(Text, { fontSize: "sm", fontWeight: "600", color: "gray.800", noOfLines: 1, children: currentOrg.name })
1299
- ] }) : /* @__PURE__ */ jsx(Text, { fontSize: "sm", color: "gray.500", children: "Select organization" }),
1300
- /* @__PURE__ */ jsx(Text, { as: "span", fontSize: "xs", color: "gray.500", "aria-hidden": "true", children: "\u25BE" })
1301
- ] })
1302
- }
1303
- ),
1304
- /* @__PURE__ */ jsx(Portal, { children: /* @__PURE__ */ jsxs(MenuList, { zIndex: 1500, children: [
1305
- others.length === 0 && /* @__PURE__ */ jsx(MenuItem, { isDisabled: true, children: /* @__PURE__ */ jsx(Text, { fontSize: "sm", color: "gray.500", children: "No other organizations" }) }),
1306
- others.map((o) => /* @__PURE__ */ jsx(
1307
- MenuItem,
1308
- {
1309
- onClick: () => {
1310
- void switchOrganization(o.id);
1311
- },
1312
- children: /* @__PURE__ */ jsxs(HStack, { spacing: 2, align: "center", children: [
1313
- /* @__PURE__ */ jsx(OrgBadge, { name: o.name, logoUrl: o.logoUrl, brandColor: o.brandColor, size: "20px" }),
1314
- /* @__PURE__ */ jsx(Flex, { direction: "column", children: /* @__PURE__ */ jsx(Text, { fontSize: "sm", fontWeight: "600", children: o.name }) })
2021
+ /* @__PURE__ */ jsx(Text, { overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap", children: currentOrg?.name || "No organizations" })
1315
2022
  ] })
2023
+ }
2024
+ ),
2025
+ /* @__PURE__ */ jsx(Portal, { children: /* @__PURE__ */ jsxs(
2026
+ MenuList,
2027
+ {
2028
+ bg: currentOrg?.id ? selectedOrgMenuBg : "gray.100",
2029
+ borderColor: currentOrg?.id ? selectedOrgColor : "gray.300",
2030
+ color: currentOrg?.id ? "white" : "gray.800",
2031
+ mt: "1",
2032
+ minW: "13rem",
2033
+ maxH: "60vh",
2034
+ overflowY: "auto",
2035
+ zIndex: "modal",
2036
+ boxShadow: "2xl",
2037
+ children: [
2038
+ unselectedOrganizations.map((o) => {
2039
+ const orgBrandColor = getOrganizationBrandColor(o);
2040
+ return /* @__PURE__ */ jsx(
2041
+ MenuItem,
2042
+ {
2043
+ onClick: () => switchOrganization?.(o.id),
2044
+ bg: "transparent",
2045
+ color: currentOrg?.id ? "white" : "inherit",
2046
+ _hover: {
2047
+ bg: currentOrg?.id ? lightenHexColor(selectedOrgBrandColor || "#ea6a3a", 0.2) || "#555555" : "gray.100",
2048
+ color: currentOrg?.id ? "white" : "gray.900"
2049
+ },
2050
+ _focus: {
2051
+ bg: currentOrg?.id ? lightenHexColor(selectedOrgBrandColor || "#ea6a3a", 0.2) || "#555555" : "gray.100",
2052
+ color: currentOrg?.id ? "white" : "gray.900"
2053
+ },
2054
+ _active: {
2055
+ bg: currentOrg?.id ? lightenHexColor(selectedOrgBrandColor || "#ea6a3a", 0.24) || "#5d5d5d" : "gray.200",
2056
+ color: currentOrg?.id ? "white" : "gray.900"
2057
+ },
2058
+ children: /* @__PURE__ */ jsxs(Flex, { justify: "space-between", align: "center", width: "100%", overflow: "hidden", children: [
2059
+ /* @__PURE__ */ jsxs(HStack, { minW: 0, flex: "1", spacing: "2.5", children: [
2060
+ /* @__PURE__ */ jsx(
2061
+ OrgBadge,
2062
+ {
2063
+ name: o.name,
2064
+ logoUrl: o.logoUrl,
2065
+ brandColor: orgBrandColor,
2066
+ size: "24px"
2067
+ }
2068
+ ),
2069
+ /* @__PURE__ */ jsx(
2070
+ Text,
2071
+ {
2072
+ overflow: "hidden",
2073
+ textOverflow: "ellipsis",
2074
+ whiteSpace: "nowrap",
2075
+ flex: "1",
2076
+ children: o.name
2077
+ }
2078
+ )
2079
+ ] }),
2080
+ /* @__PURE__ */ jsx(
2081
+ Text,
2082
+ {
2083
+ fontSize: "xs",
2084
+ color: currentOrg?.id ? "whiteAlpha.700" : "gray.500",
2085
+ ml: 2,
2086
+ flexShrink: 0,
2087
+ children: o.id.slice(-8)
2088
+ }
2089
+ )
2090
+ ] })
2091
+ },
2092
+ o.id
2093
+ );
2094
+ }),
2095
+ /* @__PURE__ */ jsx(MenuDivider, { my: 0, borderColor: currentOrg?.id ? "whiteAlpha.300" : void 0 }),
2096
+ /* @__PURE__ */ jsx(
2097
+ MenuItem,
2098
+ {
2099
+ onClick: () => window.dispatchEvent(new CustomEvent("open-create-org")),
2100
+ fontWeight: "bold",
2101
+ bg: "transparent",
2102
+ color: currentOrg?.id ? "white" : "inherit",
2103
+ my: 0,
2104
+ _hover: {
2105
+ bg: currentOrg?.id ? lightenHexColor(selectedOrgBrandColor || "#ea6a3a", 0.2) || "#555555" : "gray.100",
2106
+ color: currentOrg?.id ? "white" : "gray.900"
2107
+ },
2108
+ _focus: {
2109
+ bg: currentOrg?.id ? lightenHexColor(selectedOrgBrandColor || "#ea6a3a", 0.2) || "#555555" : "gray.100",
2110
+ color: currentOrg?.id ? "white" : "gray.900"
2111
+ },
2112
+ _active: {
2113
+ bg: currentOrg?.id ? lightenHexColor(selectedOrgBrandColor || "#ea6a3a", 0.24) || "#5d5d5d" : "gray.200",
2114
+ color: currentOrg?.id ? "white" : "gray.900"
2115
+ },
2116
+ fontSize: "sm",
2117
+ children: "+ New Organization"
2118
+ }
2119
+ )
2120
+ ]
2121
+ }
2122
+ ) })
2123
+ ] })
2124
+ ] });
2125
+ }
2126
+ var OrgPill_default = OrgPill;
2127
+ function ModePill() {
2128
+ const mode = useShellMode();
2129
+ if (!mode) return null;
2130
+ const { currentMode, modes, switchMode, getModeConfig } = mode;
2131
+ const modeConfig = getModeConfig();
2132
+ if (!modeConfig) return null;
2133
+ const hasMultipleModes = modes.length > 1;
2134
+ const isDisabled = !hasMultipleModes;
2135
+ return /* @__PURE__ */ jsx(Box, { mx: "4", mb: "4", children: /* @__PURE__ */ jsxs(Menu, { gutter: 0, children: [
2136
+ /* @__PURE__ */ jsx(
2137
+ MenuButton,
2138
+ {
2139
+ as: Button,
2140
+ leftIcon: modeConfig.icon,
2141
+ rightIcon: /* @__PURE__ */ jsx(FiChevronDown, {}),
2142
+ size: "sm",
2143
+ width: "full",
2144
+ bg: modeConfig.primaryColor,
2145
+ borderColor: modeConfig.primaryColor,
2146
+ color: modeConfig.white,
2147
+ _disabled: {
2148
+ bg: modeConfig.primaryColor,
2149
+ borderColor: modeConfig.primaryColor,
2150
+ color: modeConfig.white,
2151
+ cursor: "not-allowed",
2152
+ opacity: 1
1316
2153
  },
1317
- o.id
1318
- )),
1319
- createOrgHref && /* @__PURE__ */ jsxs(Fragment, { children: [
1320
- /* @__PURE__ */ jsx(MenuDivider, {}),
1321
- /* @__PURE__ */ jsx(MenuItem, { as: "a", href: createOrgHref, children: /* @__PURE__ */ jsx(Text, { fontSize: "sm", color: "brand.500", fontWeight: "600", children: "Create organization" }) })
2154
+ isDisabled,
2155
+ _hover: {
2156
+ bg: modeConfig.primaryColor,
2157
+ color: modeConfig.white
2158
+ },
2159
+ _active: {
2160
+ bg: modeConfig.primaryColor,
2161
+ color: modeConfig.white
2162
+ },
2163
+ children: modeConfig.name
2164
+ }
2165
+ ),
2166
+ hasMultipleModes && /* @__PURE__ */ jsx(MenuList, { children: modes.map((m) => /* @__PURE__ */ jsx(
2167
+ MenuItem,
2168
+ {
2169
+ onClick: () => switchMode(m.id),
2170
+ bg: "transparent",
2171
+ color: currentMode === m.id ? m.primaryColor : "inherit",
2172
+ _hover: { bg: m.bgColor, color: m.primaryColor },
2173
+ icon: m.icon,
2174
+ children: m.name
2175
+ },
2176
+ m.id
2177
+ )) })
2178
+ ] }) });
2179
+ }
2180
+ var ModePill_default = ModePill;
2181
+ function Sidebar({ onClose, id }) {
2182
+ const { brandLogoSrc } = useShellChrome();
2183
+ const navItems = useShellNavItems()?.items ?? [];
2184
+ const footer = useShellFooter();
2185
+ const org = useShellOrganization();
2186
+ const currentOrg = org?.currentOrg ?? null;
2187
+ const location = useLocation();
2188
+ const sidebarBg = useColorModeValue("white", "gray.900");
2189
+ const sidebarBorderColor = useColorModeValue("gray.200", "gray.700");
2190
+ const [expandedMenu, setExpandedMenu] = useState(null);
2191
+ useEffect(() => {
2192
+ const activeMenu = navItems.find(
2193
+ (item) => item.children && item.children.some((child) => {
2194
+ if (!child.href) return false;
2195
+ const childPath = child.href.split("?")[0];
2196
+ if (!childPath) return false;
2197
+ return location.pathname === childPath || location.pathname.startsWith(`${childPath}/`);
2198
+ })
2199
+ )?.name || null;
2200
+ setExpandedMenu(activeMenu);
2201
+ }, [location.pathname, navItems]);
2202
+ const handleMenuToggle = (menuKey) => {
2203
+ if (!menuKey) {
2204
+ setExpandedMenu(null);
2205
+ return;
2206
+ }
2207
+ setExpandedMenu((prev) => prev === menuKey ? null : menuKey);
2208
+ };
2209
+ return /* @__PURE__ */ jsxs(
2210
+ Flex,
2211
+ {
2212
+ id: id || "sidebar-container",
2213
+ transition: "3s ease",
2214
+ bg: sidebarBg,
2215
+ borderRight: "1px",
2216
+ borderRightColor: sidebarBorderColor,
2217
+ w: { base: "full", md: 60 },
2218
+ pos: "fixed",
2219
+ h: "100vh",
2220
+ direction: "column",
2221
+ overflow: "hidden",
2222
+ children: [
2223
+ /* @__PURE__ */ jsxs(Flex, { alignItems: "center", mx: "8", mt: "3", mb: "2", justifyContent: "space-between", flexShrink: 0, children: [
2224
+ /* @__PURE__ */ jsx(Box, { h: "40px", children: brandLogoSrc ? /* @__PURE__ */ jsx(BrandLogo_default, { src: brandLogoSrc, className: "h-full w-auto object-contain" }) : null }),
2225
+ onClose ? /* @__PURE__ */ jsx(
2226
+ IconButton,
2227
+ {
2228
+ display: { base: "flex", md: "none" },
2229
+ onClick: onClose,
2230
+ variant: "outline",
2231
+ "aria-label": "close menu",
2232
+ icon: /* @__PURE__ */ jsx(FiX, {})
2233
+ }
2234
+ ) : null
2235
+ ] }),
2236
+ /* @__PURE__ */ jsxs(
2237
+ Box,
2238
+ {
2239
+ flex: "1",
2240
+ overflowY: "auto",
2241
+ css: {
2242
+ "&::-webkit-scrollbar": { width: "8px" },
2243
+ "&::-webkit-scrollbar-track": { background: "transparent" },
2244
+ "&::-webkit-scrollbar-thumb": { background: "#CBD5E0", borderRadius: "4px" },
2245
+ "&::-webkit-scrollbar-thumb:hover": { background: "#A0AEC0" }
2246
+ },
2247
+ children: [
2248
+ currentOrg?.logoUrl && /* @__PURE__ */ jsx(Box, { mx: "4", mb: "3", children: /* @__PURE__ */ jsx(
2249
+ Image,
2250
+ {
2251
+ src: currentOrg.logoUrl,
2252
+ alt: `${currentOrg.name} logo`,
2253
+ maxH: "70px",
2254
+ w: "full",
2255
+ objectFit: "contain",
2256
+ borderRadius: "md"
2257
+ }
2258
+ ) }),
2259
+ /* @__PURE__ */ jsx(OrgPill_default, {}),
2260
+ /* @__PURE__ */ jsx(ModePill_default, {}),
2261
+ navItems.map((link) => /* @__PURE__ */ jsx(
2262
+ NavItem_default,
2263
+ {
2264
+ icon: link.icon,
2265
+ brandIcon: link.brandIcon,
2266
+ href: link.href,
2267
+ subItems: link.children,
2268
+ badge: link.badge,
2269
+ subLabel: link.subLabel,
2270
+ action: link.action,
2271
+ menuKey: String(link.name),
2272
+ isExpanded: expandedMenu === link.name,
2273
+ onToggle: handleMenuToggle,
2274
+ isDisabled: Boolean(link.disabled),
2275
+ children: link.name
2276
+ },
2277
+ link.name
2278
+ ))
2279
+ ]
2280
+ }
2281
+ ),
2282
+ footer && /* @__PURE__ */ jsx(
2283
+ Box,
2284
+ {
2285
+ px: "1",
2286
+ py: "1",
2287
+ borderTop: "1px",
2288
+ borderColor: "gray.200",
2289
+ flexShrink: 0,
2290
+ bg: sidebarBg,
2291
+ zIndex: 1,
2292
+ children: /* @__PURE__ */ jsxs(VStack, { align: "stretch", spacing: 2, px: "3", py: "2", children: [
2293
+ /* @__PURE__ */ jsx(HStack, { spacing: 1, fontSize: "xs", color: "gray.600", wrap: "wrap", children: footer.links.map((l, idx) => /* @__PURE__ */ jsxs(Box, { display: "inline-flex", alignItems: "center", children: [
2294
+ idx > 0 ? /* @__PURE__ */ jsx(Text, { color: "gray.400", mx: 1, children: "|" }) : null,
2295
+ l.external ? /* @__PURE__ */ jsx(
2296
+ Link$1,
2297
+ {
2298
+ href: l.href,
2299
+ isExternal: true,
2300
+ _hover: { textDecoration: "underline", opacity: 1 },
2301
+ children: l.label
2302
+ }
2303
+ ) : /* @__PURE__ */ jsx(
2304
+ Link$1,
2305
+ {
2306
+ as: NavLink,
2307
+ to: l.href,
2308
+ _hover: { textDecoration: "underline", opacity: 1 },
2309
+ children: l.label
2310
+ }
2311
+ )
2312
+ ] }, `${l.label}-${idx}`)) }),
2313
+ (footer.version || footer.commit || footer.environmentLabel) && /* @__PURE__ */ jsxs(HStack, { spacing: 2, fontSize: "xs", color: "gray.500", wrap: "wrap", children: [
2314
+ footer.environmentLabel ? /* @__PURE__ */ jsx(Text, { fontWeight: "semibold", children: footer.environmentLabel }) : null,
2315
+ footer.version ? /* @__PURE__ */ jsxs(Text, { children: [
2316
+ "v",
2317
+ footer.version
2318
+ ] }) : null,
2319
+ footer.commit ? /* @__PURE__ */ jsxs(Text, { fontFamily: "mono", children: [
2320
+ "#",
2321
+ footer.commit.slice(-7)
2322
+ ] }) : null
2323
+ ] })
2324
+ ] })
2325
+ }
2326
+ )
2327
+ ]
2328
+ }
2329
+ );
2330
+ }
2331
+ function Footer({ buildInfo }) {
2332
+ return /* @__PURE__ */ jsx(
2333
+ Box,
2334
+ {
2335
+ as: "footer",
2336
+ px: 4,
2337
+ py: 2,
2338
+ borderTop: "1px solid",
2339
+ borderColor: "gray.200",
2340
+ fontSize: "xs",
2341
+ color: "gray.500",
2342
+ children: /* @__PURE__ */ jsxs(Text, { children: [
2343
+ "politogy ",
2344
+ buildInfo ? `\xB7 ${buildInfo}` : ""
1322
2345
  ] })
1323
- ] }) })
2346
+ }
2347
+ );
2348
+ }
2349
+ function AppLayout({
2350
+ children,
2351
+ buildInfo,
2352
+ modalsSlot,
2353
+ notificationsSlot,
2354
+ overlaySlot
2355
+ }) {
2356
+ const [mobileOpen, setMobileOpen] = useState(false);
2357
+ return /* @__PURE__ */ jsxs(Flex, { direction: "column", minH: "100vh", children: [
2358
+ /* @__PURE__ */ jsx(
2359
+ Sidebar,
2360
+ {
2361
+ onClose: mobileOpen ? () => setMobileOpen(false) : void 0
2362
+ }
2363
+ ),
2364
+ /* @__PURE__ */ jsx(Header, { onOpen: () => setMobileOpen(true) }),
2365
+ /* @__PURE__ */ jsxs(Box, { as: "main", flex: "1", ml: { base: 0, md: 60 }, position: "relative", overflow: "auto", children: [
2366
+ children,
2367
+ notificationsSlot
2368
+ ] }),
2369
+ buildInfo ? /* @__PURE__ */ jsx(Footer, { buildInfo }) : null,
2370
+ modalsSlot,
2371
+ overlaySlot
1324
2372
  ] });
1325
2373
  }
1326
2374
  var SUPPORT_REQUEST_SUCCESS_MESSAGE = "Your support request was sent to Politogy leadership.";
@@ -1607,191 +2655,58 @@ function LifebuoyIcon() {
1607
2655
  }
1608
2656
  );
1609
2657
  }
1610
- function avatarUrlFromUser(user) {
1611
- if (!user) return void 0;
1612
- const meta = user.raw.user_metadata;
1613
- return meta?.avatar_url ?? void 0;
1614
- }
1615
- function UserMenu() {
1616
- const { user, status, signOut } = useShellAuth();
1617
- const { myProfileHref } = useShellChrome();
1618
- const linked = useShellLinkedAccounts();
1619
- const { colorMode, toggleColorMode } = useColorMode();
1620
- if (status !== "authenticated" || !user) return null;
1621
- const displayName = user.displayName ?? user.email ?? "User";
1622
- const avatarUrl = avatarUrlFromUser(user);
1623
- return /* @__PURE__ */ jsxs(Menu, { placement: "bottom-end", children: [
1624
- /* @__PURE__ */ jsx(
1625
- MenuButton,
1626
- {
1627
- "aria-label": "Open account menu",
1628
- as: Box,
1629
- cursor: "pointer",
1630
- borderRadius: "full",
1631
- _hover: { opacity: 0.85 },
1632
- children: /* @__PURE__ */ jsx(Avatar, { size: "sm", name: displayName, src: avatarUrl })
1633
- }
1634
- ),
1635
- /* @__PURE__ */ jsx(Portal, { children: /* @__PURE__ */ jsxs(MenuList, { zIndex: 1500, children: [
1636
- /* @__PURE__ */ jsxs(Box, { px: 3, py: 2, children: [
1637
- /* @__PURE__ */ jsx(Text, { fontSize: "sm", fontWeight: "600", noOfLines: 1, children: displayName }),
1638
- user.email && /* @__PURE__ */ jsx(Text, { fontSize: "xs", color: "gray.500", noOfLines: 1, children: user.email })
1639
- ] }),
1640
- /* @__PURE__ */ jsx(MenuDivider, {}),
1641
- /* @__PURE__ */ jsx(MenuItem, { as: "a", href: myProfileHref, children: "My Profile" }),
1642
- /* @__PURE__ */ jsx(MenuItem, { onClick: toggleColorMode, children: colorMode === "light" ? "Switch to dark mode" : "Switch to light mode" }),
1643
- /* @__PURE__ */ jsx(MenuItem, { onClick: () => void signOut(), children: "Sign out" }),
1644
- linked && /* @__PURE__ */ jsxs(Fragment, { children: [
1645
- /* @__PURE__ */ jsx(MenuDivider, {}),
1646
- /* @__PURE__ */ jsx(Box, { px: 3, pt: 1, pb: 1, children: /* @__PURE__ */ jsx(Text, { fontSize: "xs", textTransform: "uppercase", letterSpacing: "0.08em", color: "gray.500", children: "Switch account" }) }),
1647
- linked.linkedAccounts.length === 0 && /* @__PURE__ */ jsx(MenuItem, { isDisabled: true, children: /* @__PURE__ */ jsx(Text, { fontSize: "sm", color: "gray.500", children: "No linked accounts" }) }),
1648
- linked.linkedAccounts.map((acct) => /* @__PURE__ */ jsx(
1649
- MenuItem,
1650
- {
1651
- onClick: () => {
1652
- void linked.switchToAccount(acct.id);
1653
- },
1654
- children: /* @__PURE__ */ jsxs(HStack, { spacing: 2, align: "center", children: [
1655
- /* @__PURE__ */ jsx(
1656
- Avatar,
1657
- {
1658
- size: "xs",
1659
- name: acct.displayName ?? acct.email,
1660
- src: acct.avatarUrl ?? void 0
1661
- }
1662
- ),
1663
- /* @__PURE__ */ jsxs(Flex, { direction: "column", minW: 0, children: [
1664
- /* @__PURE__ */ jsx(Text, { fontSize: "sm", fontWeight: "600", noOfLines: 1, children: acct.displayName ?? acct.email }),
1665
- acct.displayName && /* @__PURE__ */ jsx(Text, { fontSize: "xs", color: "gray.500", noOfLines: 1, children: acct.email })
1666
- ] })
1667
- ] })
1668
- },
1669
- acct.id
1670
- )),
1671
- /* @__PURE__ */ jsx(MenuItem, { onClick: linked.onAddAccount, children: "Add account" })
1672
- ] })
1673
- ] }) })
1674
- ] });
1675
- }
1676
- function Header({ extrasSlot }) {
1677
- const { devNotesMenu } = useShellChrome();
1678
- return /* @__PURE__ */ jsxs(
1679
- Flex,
1680
- {
1681
- as: "header",
1682
- align: "center",
1683
- px: 4,
1684
- h: "56px",
1685
- bg: "white",
1686
- borderBottom: "1px solid",
1687
- borderColor: "gray.200",
1688
- gap: 3,
1689
- children: [
1690
- /* @__PURE__ */ jsx(Heading, { size: "md", color: "brand.500", children: "politogy" }),
1691
- /* @__PURE__ */ jsx(Box, { children: /* @__PURE__ */ jsx(OrgSelector, {}) }),
1692
- /* @__PURE__ */ jsx(Spacer, {}),
1693
- extrasSlot && /* @__PURE__ */ jsx(Box, { children: extrasSlot }),
1694
- /* @__PURE__ */ jsx(SupportRequestButton, {}),
1695
- devNotesMenu,
1696
- /* @__PURE__ */ jsx(UserMenu, {})
1697
- ]
1698
- }
1699
- );
1700
- }
1701
- function Sidebar({ entries, currentApp, footerSlot }) {
1702
- return /* @__PURE__ */ jsxs(
1703
- Box,
1704
- {
1705
- as: "nav",
1706
- w: "200px",
1707
- minH: "100%",
1708
- bg: "gray.50",
1709
- borderRight: "1px solid",
1710
- borderColor: "gray.200",
1711
- p: 3,
1712
- display: "flex",
1713
- flexDirection: "column",
1714
- children: [
1715
- /* @__PURE__ */ jsx(VStack, { align: "stretch", spacing: 1, children: entries.filter((e) => e.visible !== false).map((entry) => /* @__PURE__ */ jsx(
1716
- Link$1,
1717
- {
1718
- href: entry.path,
1719
- "data-current": entry.id === currentApp,
1720
- px: 3,
1721
- py: 2,
1722
- borderRadius: "md",
1723
- fontWeight: entry.id === currentApp ? "bold" : "normal",
1724
- bg: entry.id === currentApp ? "brand.50" : "transparent",
1725
- _hover: { bg: "gray.100" },
1726
- children: /* @__PURE__ */ jsx(Text, { children: entry.label })
1727
- },
1728
- entry.id
1729
- )) }),
1730
- /* @__PURE__ */ jsx(Box, { flex: "1" }),
1731
- footerSlot && /* @__PURE__ */ jsx(Box, { pt: 3, children: footerSlot })
1732
- ]
1733
- }
1734
- );
1735
- }
1736
- function Footer({ buildInfo }) {
1737
- return /* @__PURE__ */ jsx(
1738
- Box,
1739
- {
1740
- as: "footer",
1741
- px: 4,
1742
- py: 2,
1743
- borderTop: "1px solid",
1744
- borderColor: "gray.200",
1745
- fontSize: "xs",
1746
- color: "gray.500",
1747
- children: /* @__PURE__ */ jsxs(Text, { children: [
1748
- "politogy ",
1749
- buildInfo ? `\xB7 ${buildInfo}` : ""
1750
- ] })
1751
- }
1752
- );
1753
- }
1754
- function AppLayout({
1755
- children,
1756
- buildInfo,
1757
- headerExtrasSlot,
1758
- modalsSlot,
1759
- notificationsSlot,
1760
- sidebarFooterSlot,
1761
- overlaySlot
1762
- }) {
1763
- const currentApp = useCurrentApp();
1764
- const entries = useAppRegistry();
1765
- return /* @__PURE__ */ jsxs(Flex, { direction: "column", minH: "100vh", children: [
1766
- /* @__PURE__ */ jsx(Header, { extrasSlot: headerExtrasSlot }),
1767
- /* @__PURE__ */ jsxs(Flex, { flex: "1", minH: 0, children: [
1768
- /* @__PURE__ */ jsx(Sidebar, { entries, currentApp, footerSlot: sidebarFooterSlot }),
1769
- /* @__PURE__ */ jsxs(Box, { as: "main", flex: "1", overflow: "auto", position: "relative", children: [
1770
- children,
1771
- notificationsSlot
1772
- ] })
1773
- ] }),
1774
- /* @__PURE__ */ jsx(Footer, { buildInfo }),
1775
- modalsSlot,
1776
- overlaySlot
1777
- ] });
1778
- }
1779
2658
  function ShellChrome({
1780
2659
  children,
1781
2660
  organization,
1782
2661
  linkedAccounts,
1783
2662
  support,
1784
2663
  devNotesMenu,
1785
- myProfileHref
2664
+ myProfileHref,
2665
+ mode,
2666
+ navItems,
2667
+ navigationPreference,
2668
+ role,
2669
+ footer,
2670
+ brandLogoSrc,
2671
+ headerIconsSlot,
2672
+ organizationSettingsHref,
2673
+ showContinueOnboarding,
2674
+ onContinueOnboarding,
2675
+ pageTitle,
2676
+ breadcrumbs,
2677
+ headerActions
1786
2678
  }) {
1787
2679
  const chrome = useMemo(
1788
2680
  () => ({
1789
2681
  devNotesMenu: devNotesMenu ?? null,
1790
- myProfileHref: myProfileHref ?? "/my-profile"
2682
+ myProfileHref: myProfileHref ?? "/my-profile",
2683
+ brandLogoSrc,
2684
+ headerIconsSlot,
2685
+ organizationSettingsHref,
2686
+ showContinueOnboarding,
2687
+ onContinueOnboarding,
2688
+ pageTitle,
2689
+ breadcrumbs,
2690
+ headerActions
1791
2691
  }),
1792
- [devNotesMenu, myProfileHref]
2692
+ [
2693
+ devNotesMenu,
2694
+ myProfileHref,
2695
+ brandLogoSrc,
2696
+ headerIconsSlot,
2697
+ organizationSettingsHref,
2698
+ showContinueOnboarding,
2699
+ onContinueOnboarding,
2700
+ pageTitle,
2701
+ breadcrumbs,
2702
+ headerActions
2703
+ ]
2704
+ );
2705
+ const navItemsValue = useMemo(
2706
+ () => navItems ? { items: navItems } : null,
2707
+ [navItems]
1793
2708
  );
1794
- return /* @__PURE__ */ jsx(ShellOrgContext.Provider, { value: organization ?? null, children: /* @__PURE__ */ jsx(ShellLinkedAccountsContext.Provider, { value: linkedAccounts ?? null, children: /* @__PURE__ */ jsx(ShellSupportProviderContext.Provider, { value: support ?? null, children: /* @__PURE__ */ jsx(ShellChromeContext.Provider, { value: chrome, children }) }) }) });
2709
+ return /* @__PURE__ */ jsx(ShellOrgContext.Provider, { value: organization ?? null, children: /* @__PURE__ */ jsx(ShellLinkedAccountsContext.Provider, { value: linkedAccounts ?? null, children: /* @__PURE__ */ jsx(ShellSupportProviderContext.Provider, { value: support ?? null, children: /* @__PURE__ */ jsx(ShellModeContext.Provider, { value: mode ?? null, children: /* @__PURE__ */ jsx(ShellNavItemsContext.Provider, { value: navItemsValue, children: /* @__PURE__ */ jsx(ShellNavigationPreferenceContext.Provider, { value: navigationPreference ?? null, children: /* @__PURE__ */ jsx(ShellRoleContext.Provider, { value: role ?? null, children: /* @__PURE__ */ jsx(ShellFooterContext.Provider, { value: footer ?? null, children: /* @__PURE__ */ jsx(ShellChromeContext.Provider, { value: chrome, children }) }) }) }) }) }) }) }) });
1795
2710
  }
1796
2711
 
1797
2712
  // src/sw/registerShellPrecache.ts
@@ -1824,6 +2739,6 @@ function buildSpeculationRules(currentApp, registry) {
1824
2739
  return JSON.stringify(payload);
1825
2740
  }
1826
2741
 
1827
- export { AppLayout, BreadcrumbBar, Card, Footer, GlobalUiIdProvider, Header, HeaderTabBar, OrgSelector, PageContainer, PageHeader, ShellChrome, ShellChromeContext, ShellLinkedAccountsContext, ShellOrgContext, ShellProvider, ShellSupportProviderContext, Sidebar, SupportRequestButton, UserMenu, buildSpeculationRules, politogyTheme, registerShellPrecache, useAppRegistry, useCurrentApp, useShellAuth, useShellChrome, useShellLinkedAccounts, useShellOrganization, useShellSupport };
2742
+ export { AppLayout, BrandIcon, BrandLogo, BreadcrumbBar, Card, Footer, GlobalUiIdProvider, Header, HeaderTabBar, ModePill, NavItem, OrgPill, OrgPill as OrgSelector, PageContainer, PageHeader, ShellChrome, ShellChromeContext, ShellFooterContext, ShellLinkedAccountsContext, ShellModeContext, ShellNavItemsContext, ShellNavigationPreferenceContext, ShellOrgContext, ShellProvider, ShellRoleContext, ShellSupportProviderContext, Sidebar, SupportRequestButton, UserMenu, buildSpeculationRules, getOrganizationBadgeLetters, getOrganizationBrandColor, getUserDisplayName, hexToRgba, lightenHexColor, normalizeHexColor, politogyTheme, registerShellPrecache, useAppRegistry, useCurrentApp, useShellAuth, useShellChrome, useShellFooter, useShellLinkedAccounts, useShellMode, useShellNavItems, useShellNavigationPreference, useShellOrganization, useShellRole, useShellSupport };
1828
2743
  //# sourceMappingURL=index.js.map
1829
2744
  //# sourceMappingURL=index.js.map