@the-portland-company/shell 0.10.2 → 0.11.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.d.cts CHANGED
@@ -1,7 +1,8 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
2
  import * as react from 'react';
3
- import { ReactNode, CSSProperties } from 'react';
3
+ import { ReactNode, CSSProperties, ReactElement } from 'react';
4
4
  import { User, Session, SupabaseClient } from '@supabase/supabase-js';
5
+ import { IconButtonProps } from '@chakra-ui/react';
5
6
 
6
7
  declare const politogyTheme: Record<string, any>;
7
8
 
@@ -633,6 +634,33 @@ interface BrandIconProps {
633
634
  */
634
635
  declare function BrandIcon({ name, size, className, style, alt, basePath, }: BrandIconProps): react_jsx_runtime.JSX.Element;
635
636
 
637
+ /**
638
+ * The six canonical top-bar action slots (Reference/Global-Rules → Tabs & UI
639
+ * Styling). Each slot's GLYPH is unique and comes from the Brand API
640
+ * `topbarIcons.items.*` tokens, exposed as `--topbar-icon-<slot>` CSS vars
641
+ * whose value is the brand-icon NAME. Every OTHER property — size, gap, color,
642
+ * hover, selected — is universal across all six slots.
643
+ */
644
+ type TopBarIconSlot = 'comms-fuel' | 'apps' | 'notifications' | 'alerts' | 'support' | 'dark-mode';
645
+ interface TopBarIconProps extends Omit<IconButtonProps, 'icon' | 'aria-label'> {
646
+ slot: TopBarIconSlot;
647
+ 'aria-label': string;
648
+ /**
649
+ * Rendered when the Brand API has no glyph name for this slot (token unset,
650
+ * stylesheet not yet loaded, or SSR). Keeps the top bar populated instead of
651
+ * flashing an empty button.
652
+ */
653
+ fallbackIcon: ReactElement;
654
+ /** Marks the slot active — resolves the universal selected-state tokens. */
655
+ isSelected?: boolean;
656
+ }
657
+ /**
658
+ * A single top-bar action icon. Use this for EVERY top-bar slot so the six
659
+ * icons share one universal treatment — never give one slot a bespoke size,
660
+ * spacing, hover, or selected style.
661
+ */
662
+ declare const TopBarIcon: react.ForwardRefExoticComponent<TopBarIconProps & react.RefAttributes<HTMLButtonElement>>;
663
+
636
664
  /**
637
665
  * Support icon + modal rendered in the header. Reads auth, org, and support
638
666
  * handler from ShellProvider. Renders nothing when the host app didn't supply
@@ -818,4 +846,4 @@ declare function registerShellPrecache(opts?: RegisterShellPrecacheOptions): Pro
818
846
  */
819
847
  declare function buildSpeculationRules(currentApp: string, registry: AppRegistryEntry[]): string | null;
820
848
 
821
- export { AppLayout, type AppRegistryEntry, BrandIcon, BrandLogo, BreadcrumbBar, Card, CommitCopyButton, type CommitCopyButtonProps, Footer, GlobalUiIdProvider, Header, HeaderTabBar, type HeaderTabBarItem, ModePill, NavItem, OrgPill, OrgPill as OrgSelector, PageContainer, PageHeader, type ShellActiveRoleConfig, type ShellAuthStatus, type ShellAuthValue, ShellChrome, ShellChromeContext, type ShellChromeProps, type ShellChromeValue, ShellFooterContext, type ShellFooterLink, type ShellFooterValue, type ShellInjectedAuth, type ShellLinkedAccount, ShellLinkedAccountsContext, type ShellLinkedAccountsValue, type ShellModeConfig, ShellModeContext, type ShellModeValue, type ShellNavItem, ShellNavItemsContext, type ShellNavItemsValue, ShellNavigationPreferenceContext, type ShellNavigationPreferenceValue, ShellOrgContext, type ShellOrganization, type ShellOrganizationValue, ShellProvider, type ShellProviderProps, ShellRoleContext, type ShellRoleValue, type ShellSlots, type ShellSupportContext, ShellSupportProviderContext, type ShellSupportValue, type ShellUser, Sidebar, SupportRequestButton, UserMenu, buildSpeculationRules, getOrganizationBadgeLetters, getOrganizationBrandColor, getUserDisplayName, hexToRgba, lightenHexColor, normalizeHexColor, politogyTheme, registerShellPrecache, useAppRegistry, useCurrentApp, useShellAuth, useShellChrome, useShellFooter, useShellLinkedAccounts, useShellMode, useShellNavItems, useShellNavigationPreference, useShellOrganization, useShellRole, useShellSupport };
849
+ export { AppLayout, type AppRegistryEntry, BrandIcon, BrandLogo, BreadcrumbBar, Card, CommitCopyButton, type CommitCopyButtonProps, Footer, GlobalUiIdProvider, Header, HeaderTabBar, type HeaderTabBarItem, ModePill, NavItem, OrgPill, OrgPill as OrgSelector, PageContainer, PageHeader, type ShellActiveRoleConfig, type ShellAuthStatus, type ShellAuthValue, ShellChrome, ShellChromeContext, type ShellChromeProps, type ShellChromeValue, ShellFooterContext, type ShellFooterLink, type ShellFooterValue, type ShellInjectedAuth, type ShellLinkedAccount, ShellLinkedAccountsContext, type ShellLinkedAccountsValue, type ShellModeConfig, ShellModeContext, type ShellModeValue, type ShellNavItem, ShellNavItemsContext, type ShellNavItemsValue, ShellNavigationPreferenceContext, type ShellNavigationPreferenceValue, ShellOrgContext, type ShellOrganization, type ShellOrganizationValue, ShellProvider, type ShellProviderProps, ShellRoleContext, type ShellRoleValue, type ShellSlots, type ShellSupportContext, ShellSupportProviderContext, type ShellSupportValue, type ShellUser, Sidebar, SupportRequestButton, TopBarIcon, type TopBarIconProps, type TopBarIconSlot, UserMenu, buildSpeculationRules, getOrganizationBadgeLetters, getOrganizationBrandColor, getUserDisplayName, hexToRgba, lightenHexColor, normalizeHexColor, politogyTheme, registerShellPrecache, useAppRegistry, useCurrentApp, useShellAuth, useShellChrome, useShellFooter, useShellLinkedAccounts, useShellMode, useShellNavItems, useShellNavigationPreference, useShellOrganization, useShellRole, useShellSupport };
package/dist/index.d.ts CHANGED
@@ -1,7 +1,8 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
2
  import * as react from 'react';
3
- import { ReactNode, CSSProperties } from 'react';
3
+ import { ReactNode, CSSProperties, ReactElement } from 'react';
4
4
  import { User, Session, SupabaseClient } from '@supabase/supabase-js';
5
+ import { IconButtonProps } from '@chakra-ui/react';
5
6
 
6
7
  declare const politogyTheme: Record<string, any>;
7
8
 
@@ -633,6 +634,33 @@ interface BrandIconProps {
633
634
  */
634
635
  declare function BrandIcon({ name, size, className, style, alt, basePath, }: BrandIconProps): react_jsx_runtime.JSX.Element;
635
636
 
637
+ /**
638
+ * The six canonical top-bar action slots (Reference/Global-Rules → Tabs & UI
639
+ * Styling). Each slot's GLYPH is unique and comes from the Brand API
640
+ * `topbarIcons.items.*` tokens, exposed as `--topbar-icon-<slot>` CSS vars
641
+ * whose value is the brand-icon NAME. Every OTHER property — size, gap, color,
642
+ * hover, selected — is universal across all six slots.
643
+ */
644
+ type TopBarIconSlot = 'comms-fuel' | 'apps' | 'notifications' | 'alerts' | 'support' | 'dark-mode';
645
+ interface TopBarIconProps extends Omit<IconButtonProps, 'icon' | 'aria-label'> {
646
+ slot: TopBarIconSlot;
647
+ 'aria-label': string;
648
+ /**
649
+ * Rendered when the Brand API has no glyph name for this slot (token unset,
650
+ * stylesheet not yet loaded, or SSR). Keeps the top bar populated instead of
651
+ * flashing an empty button.
652
+ */
653
+ fallbackIcon: ReactElement;
654
+ /** Marks the slot active — resolves the universal selected-state tokens. */
655
+ isSelected?: boolean;
656
+ }
657
+ /**
658
+ * A single top-bar action icon. Use this for EVERY top-bar slot so the six
659
+ * icons share one universal treatment — never give one slot a bespoke size,
660
+ * spacing, hover, or selected style.
661
+ */
662
+ declare const TopBarIcon: react.ForwardRefExoticComponent<TopBarIconProps & react.RefAttributes<HTMLButtonElement>>;
663
+
636
664
  /**
637
665
  * Support icon + modal rendered in the header. Reads auth, org, and support
638
666
  * handler from ShellProvider. Renders nothing when the host app didn't supply
@@ -818,4 +846,4 @@ declare function registerShellPrecache(opts?: RegisterShellPrecacheOptions): Pro
818
846
  */
819
847
  declare function buildSpeculationRules(currentApp: string, registry: AppRegistryEntry[]): string | null;
820
848
 
821
- export { AppLayout, type AppRegistryEntry, BrandIcon, BrandLogo, BreadcrumbBar, Card, CommitCopyButton, type CommitCopyButtonProps, Footer, GlobalUiIdProvider, Header, HeaderTabBar, type HeaderTabBarItem, ModePill, NavItem, OrgPill, OrgPill as OrgSelector, PageContainer, PageHeader, type ShellActiveRoleConfig, type ShellAuthStatus, type ShellAuthValue, ShellChrome, ShellChromeContext, type ShellChromeProps, type ShellChromeValue, ShellFooterContext, type ShellFooterLink, type ShellFooterValue, type ShellInjectedAuth, type ShellLinkedAccount, ShellLinkedAccountsContext, type ShellLinkedAccountsValue, type ShellModeConfig, ShellModeContext, type ShellModeValue, type ShellNavItem, ShellNavItemsContext, type ShellNavItemsValue, ShellNavigationPreferenceContext, type ShellNavigationPreferenceValue, ShellOrgContext, type ShellOrganization, type ShellOrganizationValue, ShellProvider, type ShellProviderProps, ShellRoleContext, type ShellRoleValue, type ShellSlots, type ShellSupportContext, ShellSupportProviderContext, type ShellSupportValue, type ShellUser, Sidebar, SupportRequestButton, UserMenu, buildSpeculationRules, getOrganizationBadgeLetters, getOrganizationBrandColor, getUserDisplayName, hexToRgba, lightenHexColor, normalizeHexColor, politogyTheme, registerShellPrecache, useAppRegistry, useCurrentApp, useShellAuth, useShellChrome, useShellFooter, useShellLinkedAccounts, useShellMode, useShellNavItems, useShellNavigationPreference, useShellOrganization, useShellRole, useShellSupport };
849
+ export { AppLayout, type AppRegistryEntry, BrandIcon, BrandLogo, BreadcrumbBar, Card, CommitCopyButton, type CommitCopyButtonProps, Footer, GlobalUiIdProvider, Header, HeaderTabBar, type HeaderTabBarItem, ModePill, NavItem, OrgPill, OrgPill as OrgSelector, PageContainer, PageHeader, type ShellActiveRoleConfig, type ShellAuthStatus, type ShellAuthValue, ShellChrome, ShellChromeContext, type ShellChromeProps, type ShellChromeValue, ShellFooterContext, type ShellFooterLink, type ShellFooterValue, type ShellInjectedAuth, type ShellLinkedAccount, ShellLinkedAccountsContext, type ShellLinkedAccountsValue, type ShellModeConfig, ShellModeContext, type ShellModeValue, type ShellNavItem, ShellNavItemsContext, type ShellNavItemsValue, ShellNavigationPreferenceContext, type ShellNavigationPreferenceValue, ShellOrgContext, type ShellOrganization, type ShellOrganizationValue, ShellProvider, type ShellProviderProps, ShellRoleContext, type ShellRoleValue, type ShellSlots, type ShellSupportContext, ShellSupportProviderContext, type ShellSupportValue, type ShellUser, Sidebar, SupportRequestButton, TopBarIcon, type TopBarIconProps, type TopBarIconSlot, UserMenu, buildSpeculationRules, getOrganizationBadgeLetters, getOrganizationBrandColor, getUserDisplayName, hexToRgba, lightenHexColor, normalizeHexColor, politogyTheme, registerShellPrecache, useAppRegistry, useCurrentApp, useShellAuth, useShellChrome, useShellFooter, useShellLinkedAccounts, useShellMode, useShellNavItems, useShellNavigationPreference, useShellOrganization, useShellRole, useShellSupport };
package/dist/index.js CHANGED
@@ -1,8 +1,8 @@
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, useClipboard, Icon, Image, useDisclosure, useToast, Modal, ModalOverlay, ModalContent, ModalHeader, ModalCloseButton, ModalBody, Textarea, ModalFooter } from '@chakra-ui/react';
2
- import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
1
+ import { extendTheme, IconButton, Tooltip, ChakraProvider, useColorModeValue, Flex, Menu, MenuButton, HStack, Avatar, VStack, Text, Box, Portal, MenuList, MenuItem, MenuDivider, Badge, Link as Link$1, Collapse, Skeleton, Button, useClipboard, Icon, Image, useDisclosure, useToast, Modal, ModalOverlay, ModalContent, ModalHeader, ModalCloseButton, ModalBody, Textarea, ModalFooter } from '@chakra-ui/react';
2
+ import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
3
3
  import clsx2 from 'clsx';
4
4
  import { Link, useLocation, useNavigate, NavLink } from 'react-router-dom';
5
- import { createContext, useEffect, useState, useMemo, useContext, useCallback } from 'react';
5
+ import { createContext, forwardRef, useState, useEffect, useMemo, useContext, useCallback } from 'react';
6
6
  import { FiChevronDown, FiUser, FiRotateCcw, FiBriefcase, FiTrash2, FiUserPlus, FiLogOut, FiMenu, FiX } from 'react-icons/fi';
7
7
  import { keyframes } from '@emotion/react';
8
8
 
@@ -1515,19 +1515,19 @@ function Header({ onOpen, id }) {
1515
1515
  /* @__PURE__ */ jsxs(
1516
1516
  HStack,
1517
1517
  {
1518
- spacing: 2,
1518
+ spacing: "var(--topbar-icon-gap, 8px)",
1519
1519
  mr: "15px",
1520
- color: "gray.600",
1520
+ color: "var(--topbar-icon-color, #4A5568)",
1521
1521
  sx: {
1522
1522
  '& button:not([role="menuitem"]):not([data-menu-item])': {
1523
- width: "32px",
1524
- height: "32px",
1525
- minWidth: "32px",
1523
+ width: "var(--topbar-icon-button-size, 32px)",
1524
+ height: "var(--topbar-icon-button-size, 32px)",
1525
+ minWidth: "var(--topbar-icon-button-size, 32px)",
1526
1526
  padding: 0
1527
1527
  },
1528
- '& button:not([role="menuitem"]):not([data-menu-item]) svg': {
1529
- width: "20px",
1530
- height: "20px"
1528
+ '& button:not([role="menuitem"]):not([data-menu-item]) svg, & button:not([role="menuitem"]):not([data-menu-item]) img': {
1529
+ width: "var(--topbar-icon-size, 20px)",
1530
+ height: "var(--topbar-icon-size, 20px)"
1531
1531
  }
1532
1532
  },
1533
1533
  children: [
@@ -2482,7 +2482,7 @@ function Sidebar({ onClose, id }) {
2482
2482
  bg: sidebarBg,
2483
2483
  borderRight: "1px",
2484
2484
  borderRightColor: sidebarBorderColor,
2485
- w: { base: "full", md: 60 },
2485
+ w: { base: "full", md: "var(--sidebar-width, 240px)" },
2486
2486
  pos: "fixed",
2487
2487
  h: "100vh",
2488
2488
  direction: "column",
@@ -2649,6 +2649,53 @@ function AppLayout({
2649
2649
  overlaySlot
2650
2650
  ] });
2651
2651
  }
2652
+ function useSlotGlyphName(slot) {
2653
+ const [name, setName] = useState(null);
2654
+ useEffect(() => {
2655
+ if (typeof window === "undefined") return;
2656
+ const read = () => {
2657
+ const raw = window.getComputedStyle(document.documentElement).getPropertyValue(`--topbar-icon-${slot}`).trim().replace(/^['"]|['"]$/g, "");
2658
+ setName(raw.length > 0 ? raw : null);
2659
+ };
2660
+ read();
2661
+ const observer = new MutationObserver(read);
2662
+ observer.observe(document.head, { childList: true, subtree: true });
2663
+ return () => observer.disconnect();
2664
+ }, [slot]);
2665
+ return name;
2666
+ }
2667
+ var TopBarIcon = forwardRef(
2668
+ function TopBarIcon2({ slot, fallbackIcon, isSelected, ...rest }, ref) {
2669
+ const glyphName = useSlotGlyphName(slot);
2670
+ const icon = glyphName ? /* @__PURE__ */ jsx(
2671
+ BrandIcon,
2672
+ {
2673
+ name: glyphName,
2674
+ style: {
2675
+ width: "var(--topbar-icon-size, 20px)",
2676
+ height: "var(--topbar-icon-size, 20px)"
2677
+ }
2678
+ }
2679
+ ) : fallbackIcon;
2680
+ return /* @__PURE__ */ jsx(
2681
+ IconButton,
2682
+ {
2683
+ ref,
2684
+ icon,
2685
+ variant: "ghost",
2686
+ minW: "var(--topbar-icon-button-size, 32px)",
2687
+ h: "var(--topbar-icon-button-size, 32px)",
2688
+ bg: isSelected ? "var(--topbar-icon-selected-bg, transparent)" : "transparent",
2689
+ color: isSelected ? "var(--topbar-icon-selected-color, var(--topbar-icon-color, #64748B))" : "var(--topbar-icon-color, #64748B)",
2690
+ _hover: {
2691
+ bg: "var(--topbar-icon-hover-bg, transparent)",
2692
+ color: "var(--topbar-icon-hover-color, var(--topbar-icon-color, #64748B))"
2693
+ },
2694
+ ...rest
2695
+ }
2696
+ );
2697
+ }
2698
+ );
2652
2699
  var SUPPORT_REQUEST_SUCCESS_MESSAGE = "Your support request was sent to Politogy leadership.";
2653
2700
  function splitName(value) {
2654
2701
  const trimmed = String(value ?? "").trim();
@@ -3020,6 +3067,6 @@ function buildSpeculationRules(currentApp, registry) {
3020
3067
  return JSON.stringify(payload);
3021
3068
  }
3022
3069
 
3023
- export { AppLayout, BrandIcon, BrandLogo, BreadcrumbBar, Card, CommitCopyButton, 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 };
3070
+ export { AppLayout, BrandIcon, BrandLogo, BreadcrumbBar, Card, CommitCopyButton, 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, TopBarIcon, UserMenu, buildSpeculationRules, getOrganizationBadgeLetters, getOrganizationBrandColor, getUserDisplayName, hexToRgba, lightenHexColor, normalizeHexColor, politogyTheme, registerShellPrecache, useAppRegistry, useCurrentApp, useShellAuth, useShellChrome, useShellFooter, useShellLinkedAccounts, useShellMode, useShellNavItems, useShellNavigationPreference, useShellOrganization, useShellRole, useShellSupport };
3024
3071
  //# sourceMappingURL=index.js.map
3025
3072
  //# sourceMappingURL=index.js.map