@the-portland-company/shell 0.7.0 → 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +20 -0
- package/dist/index.cjs +199 -157
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +25 -12
- package/dist/index.d.ts +25 -12
- package/dist/index.js +199 -157
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -78,6 +78,18 @@ interface ShellUser {
|
|
|
78
78
|
}
|
|
79
79
|
/** Status of the auth session lifecycle. */
|
|
80
80
|
type ShellAuthStatus = 'loading' | 'authenticated' | 'unauthenticated';
|
|
81
|
+
/**
|
|
82
|
+
* Host-app-driven auth for apps that do not authenticate through Supabase
|
|
83
|
+
* (e.g., OIDC apps like Contacts). When passed to ShellProvider it takes
|
|
84
|
+
* precedence over `supabaseClient` session tracking. The host app is
|
|
85
|
+
* responsible for building a Supabase-shaped `user.raw` (id/email/
|
|
86
|
+
* user_metadata.full_name) so chrome components render identically.
|
|
87
|
+
*/
|
|
88
|
+
interface ShellInjectedAuth {
|
|
89
|
+
status: ShellAuthStatus;
|
|
90
|
+
user: ShellUser | null;
|
|
91
|
+
signOut: () => void | Promise<void>;
|
|
92
|
+
}
|
|
81
93
|
/**
|
|
82
94
|
* One entry in the shell's app-switcher sidebar. The shell uses this list to
|
|
83
95
|
* render navigation links between sub-apps and to drive Speculation Rules
|
|
@@ -261,8 +273,11 @@ interface ShellProviderProps {
|
|
|
261
273
|
children: ReactNode;
|
|
262
274
|
/** Stable ID of the current app, e.g., 'crm'. */
|
|
263
275
|
currentApp: string;
|
|
264
|
-
/** Authenticated Supabase client owned by the host app.
|
|
265
|
-
|
|
276
|
+
/** Authenticated Supabase client owned by the host app. Optional since
|
|
277
|
+
* 0.8.0 — apps that authenticate elsewhere pass `auth` instead. */
|
|
278
|
+
supabaseClient?: SupabaseClient;
|
|
279
|
+
/** Host-driven auth (takes precedence over supabaseClient). Since 0.8.0. */
|
|
280
|
+
auth?: ShellInjectedAuth;
|
|
266
281
|
/** App registry for the sidebar. If omitted, uses the default registry shipped with the shell. */
|
|
267
282
|
appRegistry?: AppRegistryEntry[];
|
|
268
283
|
/** Optional override for the base path if the app is mounted under a sub-path (e.g., '/contacts'). */
|
|
@@ -378,7 +393,7 @@ interface ShellChromeValue {
|
|
|
378
393
|
userAvatarUrl?: string;
|
|
379
394
|
}
|
|
380
395
|
declare const ShellChromeContext: react.Context<ShellChromeValue | null>;
|
|
381
|
-
declare function ShellProvider({ children, supabaseClient, currentApp, appRegistry, basename, organization, linkedAccounts, support, devNotesMenu, myProfileHref, userAvatarUrl, }: ShellProviderProps): react_jsx_runtime.JSX.Element;
|
|
396
|
+
declare function ShellProvider({ children, supabaseClient, auth, currentApp, appRegistry, basename, organization, linkedAccounts, support, devNotesMenu, myProfileHref, userAvatarUrl, }: ShellProviderProps): react_jsx_runtime.JSX.Element;
|
|
382
397
|
|
|
383
398
|
declare function useShellAuth(): ShellAuthValue;
|
|
384
399
|
|
|
@@ -574,15 +589,13 @@ interface NavItemProps {
|
|
|
574
589
|
[key: string]: unknown;
|
|
575
590
|
}
|
|
576
591
|
/**
|
|
577
|
-
* Single sidebar nav row.
|
|
578
|
-
* react/app/src/layouts/AuthenticatedLayout.tsx
|
|
579
|
-
* with mode + navigation-preference context reads swapped for shell hooks.
|
|
592
|
+
* Single sidebar nav row. Reconciled with main-app source of truth:
|
|
593
|
+
* `react/app/src/layouts/AuthenticatedLayout.tsx` NavItem (2026-07).
|
|
580
594
|
*
|
|
581
|
-
*
|
|
582
|
-
* -
|
|
583
|
-
*
|
|
584
|
-
* -
|
|
585
|
-
* - Mode-aware hover gradient that sweeps left-to-right.
|
|
595
|
+
* Shell additions retained: `brandIcon`, `safeHref`, shell context hooks.
|
|
596
|
+
* Main-app behavior restored: gray hover (no gradient sweep), parent active
|
|
597
|
+
* when any child matches even in tabs-only mode, split effectiveHref vs
|
|
598
|
+
* href-less accordion headers.
|
|
586
599
|
*/
|
|
587
600
|
declare function NavItem({ icon, brandIcon, children, href, action, subItems, badge, subLabel, isSubItem, isExpanded, onToggle, menuKey, isDisabled: navIsDisabled, disabled, ...rest }: NavItemProps): react_jsx_runtime.JSX.Element;
|
|
588
601
|
|
|
@@ -805,4 +818,4 @@ declare function registerShellPrecache(opts?: RegisterShellPrecacheOptions): Pro
|
|
|
805
818
|
*/
|
|
806
819
|
declare function buildSpeculationRules(currentApp: string, registry: AppRegistryEntry[]): string | null;
|
|
807
820
|
|
|
808
|
-
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 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 };
|
|
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 };
|
package/dist/index.d.ts
CHANGED
|
@@ -78,6 +78,18 @@ interface ShellUser {
|
|
|
78
78
|
}
|
|
79
79
|
/** Status of the auth session lifecycle. */
|
|
80
80
|
type ShellAuthStatus = 'loading' | 'authenticated' | 'unauthenticated';
|
|
81
|
+
/**
|
|
82
|
+
* Host-app-driven auth for apps that do not authenticate through Supabase
|
|
83
|
+
* (e.g., OIDC apps like Contacts). When passed to ShellProvider it takes
|
|
84
|
+
* precedence over `supabaseClient` session tracking. The host app is
|
|
85
|
+
* responsible for building a Supabase-shaped `user.raw` (id/email/
|
|
86
|
+
* user_metadata.full_name) so chrome components render identically.
|
|
87
|
+
*/
|
|
88
|
+
interface ShellInjectedAuth {
|
|
89
|
+
status: ShellAuthStatus;
|
|
90
|
+
user: ShellUser | null;
|
|
91
|
+
signOut: () => void | Promise<void>;
|
|
92
|
+
}
|
|
81
93
|
/**
|
|
82
94
|
* One entry in the shell's app-switcher sidebar. The shell uses this list to
|
|
83
95
|
* render navigation links between sub-apps and to drive Speculation Rules
|
|
@@ -261,8 +273,11 @@ interface ShellProviderProps {
|
|
|
261
273
|
children: ReactNode;
|
|
262
274
|
/** Stable ID of the current app, e.g., 'crm'. */
|
|
263
275
|
currentApp: string;
|
|
264
|
-
/** Authenticated Supabase client owned by the host app.
|
|
265
|
-
|
|
276
|
+
/** Authenticated Supabase client owned by the host app. Optional since
|
|
277
|
+
* 0.8.0 — apps that authenticate elsewhere pass `auth` instead. */
|
|
278
|
+
supabaseClient?: SupabaseClient;
|
|
279
|
+
/** Host-driven auth (takes precedence over supabaseClient). Since 0.8.0. */
|
|
280
|
+
auth?: ShellInjectedAuth;
|
|
266
281
|
/** App registry for the sidebar. If omitted, uses the default registry shipped with the shell. */
|
|
267
282
|
appRegistry?: AppRegistryEntry[];
|
|
268
283
|
/** Optional override for the base path if the app is mounted under a sub-path (e.g., '/contacts'). */
|
|
@@ -378,7 +393,7 @@ interface ShellChromeValue {
|
|
|
378
393
|
userAvatarUrl?: string;
|
|
379
394
|
}
|
|
380
395
|
declare const ShellChromeContext: react.Context<ShellChromeValue | null>;
|
|
381
|
-
declare function ShellProvider({ children, supabaseClient, currentApp, appRegistry, basename, organization, linkedAccounts, support, devNotesMenu, myProfileHref, userAvatarUrl, }: ShellProviderProps): react_jsx_runtime.JSX.Element;
|
|
396
|
+
declare function ShellProvider({ children, supabaseClient, auth, currentApp, appRegistry, basename, organization, linkedAccounts, support, devNotesMenu, myProfileHref, userAvatarUrl, }: ShellProviderProps): react_jsx_runtime.JSX.Element;
|
|
382
397
|
|
|
383
398
|
declare function useShellAuth(): ShellAuthValue;
|
|
384
399
|
|
|
@@ -574,15 +589,13 @@ interface NavItemProps {
|
|
|
574
589
|
[key: string]: unknown;
|
|
575
590
|
}
|
|
576
591
|
/**
|
|
577
|
-
* Single sidebar nav row.
|
|
578
|
-
* react/app/src/layouts/AuthenticatedLayout.tsx
|
|
579
|
-
* with mode + navigation-preference context reads swapped for shell hooks.
|
|
592
|
+
* Single sidebar nav row. Reconciled with main-app source of truth:
|
|
593
|
+
* `react/app/src/layouts/AuthenticatedLayout.tsx` NavItem (2026-07).
|
|
580
594
|
*
|
|
581
|
-
*
|
|
582
|
-
* -
|
|
583
|
-
*
|
|
584
|
-
* -
|
|
585
|
-
* - Mode-aware hover gradient that sweeps left-to-right.
|
|
595
|
+
* Shell additions retained: `brandIcon`, `safeHref`, shell context hooks.
|
|
596
|
+
* Main-app behavior restored: gray hover (no gradient sweep), parent active
|
|
597
|
+
* when any child matches even in tabs-only mode, split effectiveHref vs
|
|
598
|
+
* href-less accordion headers.
|
|
586
599
|
*/
|
|
587
600
|
declare function NavItem({ icon, brandIcon, children, href, action, subItems, badge, subLabel, isSubItem, isExpanded, onToggle, menuKey, isDisabled: navIsDisabled, disabled, ...rest }: NavItemProps): react_jsx_runtime.JSX.Element;
|
|
588
601
|
|
|
@@ -805,4 +818,4 @@ declare function registerShellPrecache(opts?: RegisterShellPrecacheOptions): Pro
|
|
|
805
818
|
*/
|
|
806
819
|
declare function buildSpeculationRules(currentApp: string, registry: AppRegistryEntry[]): string | null;
|
|
807
820
|
|
|
808
|
-
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 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 };
|
|
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 };
|
package/dist/index.js
CHANGED
|
@@ -1120,6 +1120,7 @@ function toShellUser(session) {
|
|
|
1120
1120
|
function ShellProvider({
|
|
1121
1121
|
children,
|
|
1122
1122
|
supabaseClient,
|
|
1123
|
+
auth,
|
|
1123
1124
|
currentApp,
|
|
1124
1125
|
appRegistry,
|
|
1125
1126
|
basename,
|
|
@@ -1133,6 +1134,11 @@ function ShellProvider({
|
|
|
1133
1134
|
const [status, setStatus] = useState("loading");
|
|
1134
1135
|
const [session, setSession] = useState(null);
|
|
1135
1136
|
useEffect(() => {
|
|
1137
|
+
if (auth || !supabaseClient) {
|
|
1138
|
+
setSession(null);
|
|
1139
|
+
if (!auth) setStatus("unauthenticated");
|
|
1140
|
+
return;
|
|
1141
|
+
}
|
|
1136
1142
|
let cancelled = false;
|
|
1137
1143
|
supabaseClient.auth.getSession().then(({ data }) => {
|
|
1138
1144
|
if (cancelled) return;
|
|
@@ -1147,18 +1153,27 @@ function ShellProvider({
|
|
|
1147
1153
|
cancelled = true;
|
|
1148
1154
|
sub.data.subscription.unsubscribe();
|
|
1149
1155
|
};
|
|
1150
|
-
}, [supabaseClient]);
|
|
1151
|
-
const value = useMemo(
|
|
1152
|
-
()
|
|
1156
|
+
}, [supabaseClient, auth]);
|
|
1157
|
+
const value = useMemo(() => {
|
|
1158
|
+
if (auth) {
|
|
1159
|
+
return {
|
|
1160
|
+
status: auth.status,
|
|
1161
|
+
session: null,
|
|
1162
|
+
user: auth.user,
|
|
1163
|
+
signOut: async () => {
|
|
1164
|
+
await auth.signOut();
|
|
1165
|
+
}
|
|
1166
|
+
};
|
|
1167
|
+
}
|
|
1168
|
+
return {
|
|
1153
1169
|
status,
|
|
1154
1170
|
session,
|
|
1155
1171
|
user: toShellUser(session),
|
|
1156
1172
|
signOut: async () => {
|
|
1157
|
-
await supabaseClient
|
|
1173
|
+
await supabaseClient?.auth.signOut();
|
|
1158
1174
|
}
|
|
1159
|
-
}
|
|
1160
|
-
|
|
1161
|
-
);
|
|
1175
|
+
};
|
|
1176
|
+
}, [auth, status, session, supabaseClient]);
|
|
1162
1177
|
const meta = useMemo(
|
|
1163
1178
|
() => ({
|
|
1164
1179
|
currentApp,
|
|
@@ -1552,8 +1567,7 @@ function BrandIcon({
|
|
|
1552
1567
|
);
|
|
1553
1568
|
}
|
|
1554
1569
|
var BrandIcon_default = BrandIcon;
|
|
1555
|
-
var
|
|
1556
|
-
var MODE_PETITION = "petition";
|
|
1570
|
+
var safeHref = (h) => h && /^(https?:|mailto:|tel:|\/|#|\.)/i.test(h.trim()) ? h : "#";
|
|
1557
1571
|
function NavItem({
|
|
1558
1572
|
icon,
|
|
1559
1573
|
brandIcon,
|
|
@@ -1574,23 +1588,9 @@ function NavItem({
|
|
|
1574
1588
|
const location = useLocation();
|
|
1575
1589
|
const navigate = useNavigate();
|
|
1576
1590
|
const mode = useShellMode();
|
|
1577
|
-
const currentMode = mode?.currentMode ?? null;
|
|
1578
1591
|
const modeConfig = resolveModeConfig(mode);
|
|
1579
1592
|
const navPref = useShellNavigationPreference();
|
|
1580
1593
|
const showSubMenu = navPref?.showSubMenu ?? true;
|
|
1581
|
-
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, #ea6a3a 0%, #E63946 100%)";
|
|
1582
|
-
const gradientSweepBefore = {
|
|
1583
|
-
content: '""',
|
|
1584
|
-
position: "absolute",
|
|
1585
|
-
top: 0,
|
|
1586
|
-
left: 0,
|
|
1587
|
-
bottom: 0,
|
|
1588
|
-
width: "0%",
|
|
1589
|
-
background: navHoverGradient,
|
|
1590
|
-
transition: "width 300ms ease",
|
|
1591
|
-
pointerEvents: "none",
|
|
1592
|
-
zIndex: 0
|
|
1593
|
-
};
|
|
1594
1594
|
const isDisabled = Boolean(navIsDisabled || disabled);
|
|
1595
1595
|
const effectiveHref = href || (Array.isArray(subItems) && subItems.length > 0 ? subItems[0].href : void 0);
|
|
1596
1596
|
const effectivePathname = effectiveHref?.split("?")[0];
|
|
@@ -1600,6 +1600,7 @@ function NavItem({
|
|
|
1600
1600
|
[location.search]
|
|
1601
1601
|
);
|
|
1602
1602
|
const matchesSubItem = (itemHref) => {
|
|
1603
|
+
if (!itemHref) return false;
|
|
1603
1604
|
if (itemHref === currentFullPath) return true;
|
|
1604
1605
|
const itemPath = itemHref.split("?")[0];
|
|
1605
1606
|
const itemSearch = itemHref.includes("?") ? itemHref.split("?")[1] : "";
|
|
@@ -1643,83 +1644,130 @@ function NavItem({
|
|
|
1643
1644
|
return effectivePathname !== `/${location.pathname.split("/")[1]}/dashboard` && location.pathname.startsWith(effectivePathname + "/");
|
|
1644
1645
|
})();
|
|
1645
1646
|
const hasSubItems = showSubMenu && Array.isArray(subItems) && subItems.length > 0;
|
|
1646
|
-
const hasActiveChild =
|
|
1647
|
+
const hasActiveChild = Array.isArray(subItems) && subItems.some((item) => matchesSubItem(item.href || ""));
|
|
1647
1648
|
const isParentActive = isActive || hasActiveChild;
|
|
1648
1649
|
const isSubMenuOpen = isExpanded !== void 0 ? isExpanded : hasSubItems && subItems.some((item) => matchesSubItem(item.href || ""));
|
|
1649
1650
|
const expandedRowBg = isParentActive ? modeConfig?.primaryColor || "brand.500" : isSubMenuOpen ? "gray.100" : "transparent";
|
|
1650
1651
|
const expandedRowTextColor = isParentActive ? "white" : isSubMenuOpen ? "gray.900" : "gray.600";
|
|
1651
1652
|
const disabledRowBg = isSubItem ? "gray.50" : "transparent";
|
|
1652
1653
|
const disabledRowTextColor = "gray.400";
|
|
1654
|
+
const renderIcon = (activeForHover) => {
|
|
1655
|
+
if (brandIcon) {
|
|
1656
|
+
return /* @__PURE__ */ jsx(
|
|
1657
|
+
Box,
|
|
1658
|
+
{
|
|
1659
|
+
mr: "4",
|
|
1660
|
+
display: "inline-flex",
|
|
1661
|
+
alignItems: "center",
|
|
1662
|
+
filter: isParentActive || isActive ? "brightness(0) invert(1)" : void 0,
|
|
1663
|
+
_groupHover: isDisabled ? void 0 : {
|
|
1664
|
+
filter: activeForHover ? "brightness(0) invert(1)" : void 0
|
|
1665
|
+
},
|
|
1666
|
+
children: /* @__PURE__ */ jsx(BrandIcon_default, { name: brandIcon, size: 18 })
|
|
1667
|
+
}
|
|
1668
|
+
);
|
|
1669
|
+
}
|
|
1670
|
+
if (icon) {
|
|
1671
|
+
return /* @__PURE__ */ jsx(
|
|
1672
|
+
Box,
|
|
1673
|
+
{
|
|
1674
|
+
mr: "4",
|
|
1675
|
+
fontSize: "16",
|
|
1676
|
+
_groupHover: {
|
|
1677
|
+
color: isDisabled ? disabledRowTextColor : activeForHover ? "white" : "gray.900"
|
|
1678
|
+
},
|
|
1679
|
+
as: icon
|
|
1680
|
+
}
|
|
1681
|
+
);
|
|
1682
|
+
}
|
|
1683
|
+
return null;
|
|
1684
|
+
};
|
|
1653
1685
|
if (hasSubItems) {
|
|
1654
|
-
const headerProps = {
|
|
1655
|
-
align: "center",
|
|
1656
|
-
px: "4",
|
|
1657
|
-
py: "2.5",
|
|
1658
|
-
mx: "4",
|
|
1659
|
-
w: "auto",
|
|
1660
|
-
borderTopRadius: "lg",
|
|
1661
|
-
borderBottomRadius: isSubMenuOpen ? 0 : "lg",
|
|
1662
|
-
role: "group",
|
|
1663
|
-
cursor: isDisabled ? "not-allowed" : "pointer",
|
|
1664
|
-
opacity: 1,
|
|
1665
|
-
pointerEvents: isDisabled ? "none" : "auto",
|
|
1666
|
-
"data-nav-item-active": String(isParentActive),
|
|
1667
|
-
position: "relative",
|
|
1668
|
-
overflow: "hidden",
|
|
1669
|
-
bg: isDisabled ? disabledRowBg : expandedRowBg,
|
|
1670
|
-
color: isDisabled ? disabledRowTextColor : expandedRowTextColor,
|
|
1671
|
-
_before: isDisabled ? void 0 : gradientSweepBefore,
|
|
1672
|
-
_hover: {
|
|
1673
|
-
color: isDisabled ? disabledRowTextColor : "white",
|
|
1674
|
-
_before: isDisabled ? void 0 : { width: "100%" }
|
|
1675
|
-
},
|
|
1676
|
-
"aria-disabled": isDisabled ? "true" : "false",
|
|
1677
|
-
onClick: (e) => {
|
|
1678
|
-
if (isDisabled) return;
|
|
1679
|
-
if (effectiveHref) e.preventDefault();
|
|
1680
|
-
e.stopPropagation();
|
|
1681
|
-
onToggle?.(menuKey || null);
|
|
1682
|
-
}
|
|
1683
|
-
};
|
|
1684
1686
|
return /* @__PURE__ */ jsxs(Box, { children: [
|
|
1685
|
-
/* @__PURE__ */ jsxs(
|
|
1686
|
-
|
|
1687
|
-
|
|
1688
|
-
|
|
1689
|
-
|
|
1690
|
-
|
|
1691
|
-
|
|
1692
|
-
|
|
1693
|
-
|
|
1694
|
-
|
|
1695
|
-
|
|
1696
|
-
|
|
1697
|
-
|
|
1698
|
-
|
|
1699
|
-
|
|
1700
|
-
|
|
1701
|
-
|
|
1702
|
-
|
|
1703
|
-
|
|
1704
|
-
|
|
1705
|
-
|
|
1706
|
-
|
|
1707
|
-
|
|
1708
|
-
|
|
1709
|
-
|
|
1710
|
-
|
|
1711
|
-
|
|
1712
|
-
|
|
1713
|
-
|
|
1714
|
-
|
|
1715
|
-
|
|
1716
|
-
|
|
1717
|
-
|
|
1718
|
-
|
|
1719
|
-
|
|
1720
|
-
|
|
1721
|
-
|
|
1722
|
-
|
|
1687
|
+
effectiveHref ? /* @__PURE__ */ jsxs(
|
|
1688
|
+
Flex,
|
|
1689
|
+
{
|
|
1690
|
+
align: "center",
|
|
1691
|
+
px: "4",
|
|
1692
|
+
py: "2.5",
|
|
1693
|
+
mx: "4",
|
|
1694
|
+
w: "auto",
|
|
1695
|
+
borderTopRadius: "lg",
|
|
1696
|
+
borderBottomRadius: isSubMenuOpen ? 0 : "lg",
|
|
1697
|
+
role: "group",
|
|
1698
|
+
cursor: isDisabled ? "not-allowed" : "pointer",
|
|
1699
|
+
opacity: 1,
|
|
1700
|
+
pointerEvents: isDisabled ? "none" : "auto",
|
|
1701
|
+
"data-nav-item-active": String(isParentActive),
|
|
1702
|
+
bg: isDisabled ? disabledRowBg : expandedRowBg,
|
|
1703
|
+
color: isDisabled ? disabledRowTextColor : expandedRowTextColor,
|
|
1704
|
+
_hover: {
|
|
1705
|
+
bg: isDisabled ? disabledRowBg : isParentActive ? modeConfig?.accentColor || "brand.600" : "gray.200",
|
|
1706
|
+
color: isDisabled ? disabledRowTextColor : isParentActive ? "white" : "gray.900"
|
|
1707
|
+
},
|
|
1708
|
+
"aria-disabled": isDisabled ? "true" : "false",
|
|
1709
|
+
onClick: (e) => {
|
|
1710
|
+
if (isDisabled) return;
|
|
1711
|
+
e.preventDefault();
|
|
1712
|
+
e.stopPropagation();
|
|
1713
|
+
onToggle?.(menuKey || null);
|
|
1714
|
+
},
|
|
1715
|
+
...rest,
|
|
1716
|
+
children: [
|
|
1717
|
+
renderIcon(isParentActive),
|
|
1718
|
+
/* @__PURE__ */ jsx(Box, { flex: "1", children }),
|
|
1719
|
+
/* @__PURE__ */ jsx(
|
|
1720
|
+
Box,
|
|
1721
|
+
{
|
|
1722
|
+
as: FiChevronDown,
|
|
1723
|
+
transform: isSubMenuOpen ? "rotate(180deg)" : void 0,
|
|
1724
|
+
transition: "transform 0.2s"
|
|
1725
|
+
}
|
|
1726
|
+
)
|
|
1727
|
+
]
|
|
1728
|
+
}
|
|
1729
|
+
) : /* @__PURE__ */ jsxs(
|
|
1730
|
+
Flex,
|
|
1731
|
+
{
|
|
1732
|
+
align: "center",
|
|
1733
|
+
px: "4",
|
|
1734
|
+
py: "2.5",
|
|
1735
|
+
mx: "4",
|
|
1736
|
+
w: "auto",
|
|
1737
|
+
borderTopRadius: "lg",
|
|
1738
|
+
borderBottomRadius: isSubMenuOpen ? 0 : "lg",
|
|
1739
|
+
role: "group",
|
|
1740
|
+
cursor: isDisabled ? "not-allowed" : "pointer",
|
|
1741
|
+
opacity: 1,
|
|
1742
|
+
pointerEvents: isDisabled ? "none" : "auto",
|
|
1743
|
+
"data-nav-item-active": String(isParentActive),
|
|
1744
|
+
bg: isDisabled ? disabledRowBg : expandedRowBg,
|
|
1745
|
+
color: isDisabled ? disabledRowTextColor : expandedRowTextColor,
|
|
1746
|
+
_hover: {
|
|
1747
|
+
bg: isDisabled ? disabledRowBg : hasActiveChild ? modeConfig?.accentColor || "brand.600" : "gray.200",
|
|
1748
|
+
color: isDisabled ? disabledRowTextColor : hasActiveChild ? "white" : "gray.900"
|
|
1749
|
+
},
|
|
1750
|
+
"aria-disabled": isDisabled ? "true" : "false",
|
|
1751
|
+
onClick: (e) => {
|
|
1752
|
+
if (isDisabled) return;
|
|
1753
|
+
e.stopPropagation();
|
|
1754
|
+
onToggle?.(menuKey || null);
|
|
1755
|
+
},
|
|
1756
|
+
...rest,
|
|
1757
|
+
children: [
|
|
1758
|
+
renderIcon(hasActiveChild),
|
|
1759
|
+
/* @__PURE__ */ jsx(Box, { flex: "1", children }),
|
|
1760
|
+
/* @__PURE__ */ jsx(
|
|
1761
|
+
Box,
|
|
1762
|
+
{
|
|
1763
|
+
as: FiChevronDown,
|
|
1764
|
+
transform: isSubMenuOpen ? "rotate(180deg)" : void 0,
|
|
1765
|
+
transition: "transform 0.2s"
|
|
1766
|
+
}
|
|
1767
|
+
)
|
|
1768
|
+
]
|
|
1769
|
+
}
|
|
1770
|
+
),
|
|
1723
1771
|
/* @__PURE__ */ jsx(Collapse, { in: isSubMenuOpen, animateOpacity: true, children: /* @__PURE__ */ jsx(
|
|
1724
1772
|
Box,
|
|
1725
1773
|
{
|
|
@@ -1763,74 +1811,68 @@ function NavItem({
|
|
|
1763
1811
|
navigate(effectiveHref);
|
|
1764
1812
|
}
|
|
1765
1813
|
};
|
|
1766
|
-
|
|
1767
|
-
|
|
1814
|
+
const rowActive = isSubItem ? isActive : isParentActive;
|
|
1815
|
+
return /* @__PURE__ */ jsx(
|
|
1816
|
+
Box,
|
|
1768
1817
|
{
|
|
1769
|
-
|
|
1770
|
-
|
|
1771
|
-
py: "2.5",
|
|
1772
|
-
mx: isSubItem ? "0" : "4",
|
|
1773
|
-
w: isSubItem ? "full" : "auto",
|
|
1774
|
-
borderRadius: isSubItem ? "0" : "lg",
|
|
1775
|
-
role: "group",
|
|
1776
|
-
cursor: isDisabled ? "not-allowed" : "pointer",
|
|
1777
|
-
opacity: 1,
|
|
1778
|
-
pointerEvents: isDisabled ? "none" : "auto",
|
|
1779
|
-
"data-nav-item-active": String(isActive),
|
|
1780
|
-
position: "relative",
|
|
1781
|
-
overflow: "hidden",
|
|
1782
|
-
bg: isDisabled ? disabledRowBg : isActive ? isSubItem ? "gray.100" : modeConfig?.primaryColor || "brand.500" : "transparent",
|
|
1783
|
-
color: isDisabled ? disabledRowTextColor : isActive ? isSubItem ? modeConfig?.primaryColor || "brand.500" : "white" : "gray.600",
|
|
1784
|
-
_before: isDisabled ? void 0 : gradientSweepBefore,
|
|
1785
|
-
_hover: {
|
|
1786
|
-
color: isDisabled ? disabledRowTextColor : "white",
|
|
1787
|
-
_before: isDisabled ? void 0 : { width: "100%" }
|
|
1788
|
-
},
|
|
1789
|
-
"aria-disabled": isDisabled ? "true" : "false",
|
|
1818
|
+
as: "a",
|
|
1819
|
+
href: safeHref(effectiveHref),
|
|
1790
1820
|
onClick: handleClick,
|
|
1791
|
-
|
|
1792
|
-
|
|
1793
|
-
|
|
1794
|
-
|
|
1795
|
-
|
|
1796
|
-
|
|
1797
|
-
|
|
1798
|
-
|
|
1799
|
-
|
|
1800
|
-
|
|
1801
|
-
|
|
1802
|
-
|
|
1803
|
-
|
|
1804
|
-
|
|
1805
|
-
|
|
1806
|
-
|
|
1807
|
-
|
|
1808
|
-
|
|
1809
|
-
|
|
1810
|
-
|
|
1811
|
-
|
|
1812
|
-
|
|
1813
|
-
|
|
1814
|
-
|
|
1815
|
-
|
|
1816
|
-
|
|
1817
|
-
|
|
1818
|
-
|
|
1819
|
-
|
|
1820
|
-
|
|
1821
|
-
|
|
1822
|
-
|
|
1823
|
-
|
|
1824
|
-
|
|
1825
|
-
|
|
1826
|
-
|
|
1827
|
-
|
|
1828
|
-
|
|
1829
|
-
|
|
1830
|
-
|
|
1831
|
-
|
|
1821
|
+
style: { textDecoration: "none" },
|
|
1822
|
+
children: /* @__PURE__ */ jsxs(
|
|
1823
|
+
Flex,
|
|
1824
|
+
{
|
|
1825
|
+
align: "center",
|
|
1826
|
+
px: "4",
|
|
1827
|
+
py: "2.5",
|
|
1828
|
+
mx: isSubItem ? "0" : "4",
|
|
1829
|
+
w: isSubItem ? "full" : "auto",
|
|
1830
|
+
borderRadius: isSubItem ? "0" : "lg",
|
|
1831
|
+
role: "group",
|
|
1832
|
+
cursor: isDisabled ? "not-allowed" : "pointer",
|
|
1833
|
+
opacity: 1,
|
|
1834
|
+
pointerEvents: isDisabled ? "none" : "auto",
|
|
1835
|
+
"data-nav-item-active": String(rowActive),
|
|
1836
|
+
bg: isDisabled ? disabledRowBg : rowActive ? isSubItem ? "gray.100" : modeConfig?.primaryColor || "brand.500" : "transparent",
|
|
1837
|
+
color: isDisabled ? disabledRowTextColor : rowActive ? isSubItem ? modeConfig?.primaryColor || "brand.500" : "white" : "gray.600",
|
|
1838
|
+
_hover: {
|
|
1839
|
+
bg: isDisabled ? disabledRowBg : rowActive ? isSubItem ? "gray.200" : modeConfig?.accentColor || "brand.600" : "gray.100",
|
|
1840
|
+
color: isDisabled ? disabledRowTextColor : rowActive ? isSubItem ? modeConfig?.primaryColor || "brand.500" : "white" : "gray.900"
|
|
1841
|
+
},
|
|
1842
|
+
"aria-disabled": isDisabled ? "true" : "false",
|
|
1843
|
+
onClick: handleClick,
|
|
1844
|
+
...rest,
|
|
1845
|
+
children: [
|
|
1846
|
+
brandIcon ? /* @__PURE__ */ jsx(
|
|
1847
|
+
Box,
|
|
1848
|
+
{
|
|
1849
|
+
mr: "4",
|
|
1850
|
+
display: "inline-flex",
|
|
1851
|
+
alignItems: "center",
|
|
1852
|
+
filter: rowActive && !isSubItem ? "brightness(0) invert(1)" : void 0,
|
|
1853
|
+
children: /* @__PURE__ */ jsx(BrandIcon_default, { name: brandIcon, size: 18 })
|
|
1854
|
+
}
|
|
1855
|
+
) : icon ? /* @__PURE__ */ jsx(
|
|
1856
|
+
Box,
|
|
1857
|
+
{
|
|
1858
|
+
mr: "4",
|
|
1859
|
+
fontSize: "16",
|
|
1860
|
+
_groupHover: {
|
|
1861
|
+
color: isDisabled ? disabledRowTextColor : rowActive ? isSubItem ? modeConfig?.primaryColor || "brand.500" : "white" : "gray.900"
|
|
1862
|
+
},
|
|
1863
|
+
as: icon
|
|
1864
|
+
}
|
|
1865
|
+
) : null,
|
|
1866
|
+
/* @__PURE__ */ jsxs(Box, { flex: "1", children: [
|
|
1867
|
+
/* @__PURE__ */ jsx(Box, { children }),
|
|
1868
|
+
subLabel ? /* @__PURE__ */ jsx(Text, { mt: 0.5, fontSize: "10px", lineHeight: "1.3", color: "gray.400", children: subLabel }) : null,
|
|
1869
|
+
badge && /* @__PURE__ */ jsx(Badge, { colorScheme: "orange", size: "xs", mt: 1, fontSize: "xs", display: "block", children: badge })
|
|
1870
|
+
] })
|
|
1871
|
+
]
|
|
1872
|
+
}
|
|
1873
|
+
)
|
|
1832
1874
|
}
|
|
1833
|
-
)
|
|
1875
|
+
);
|
|
1834
1876
|
}
|
|
1835
1877
|
var NavItem_default = NavItem;
|
|
1836
1878
|
|