diff --git a/packages/frontend-app-api/src/extensions/CoreNav.tsx b/packages/frontend-app-api/src/extensions/CoreNav.tsx
index 50aa8fd408..9c829a348f 100644
--- a/packages/frontend-app-api/src/extensions/CoreNav.tsx
+++ b/packages/frontend-app-api/src/extensions/CoreNav.tsx
@@ -30,6 +30,7 @@ import {
sidebarConfig,
SidebarDivider,
SidebarItem,
+ SidebarGroup,
} from '@backstage/core-components';
// eslint-disable-next-line @backstage/no-relative-monorepo-imports
import LogoIcon from '../../../app/src/components/Root/LogoIcon';
@@ -64,6 +65,18 @@ const SidebarLogo = () => {
);
};
+const SidebarNavItem = (props: NavTarget) => {
+ const { icon: Icon, title, group, routeRef } = props;
+ const to = useRouteRef(routeRef)();
+ return group ? (
+ } label={title}>
+ {group}
+
+ ) : (
+
+ );
+};
+
export const CoreNav = createExtension({
id: 'core.nav',
at: 'core.layout/nav',
@@ -76,11 +89,6 @@ export const CoreNav = createExtension({
element: coreExtensionData.reactElement,
},
factory({ bind, inputs }) {
- const SidebarNavItem = (props: NavTarget) => {
- const { icon, title, routeRef } = props;
- const to = useRouteRef(routeRef)();
- return ;
- };
bind({
element: (
diff --git a/packages/frontend-plugin-api/src/extensions/createNavItemExtension.tsx b/packages/frontend-plugin-api/src/extensions/createNavItemExtension.tsx
index 8c55531866..723c9e9956 100644
--- a/packages/frontend-plugin-api/src/extensions/createNavItemExtension.tsx
+++ b/packages/frontend-plugin-api/src/extensions/createNavItemExtension.tsx
@@ -16,19 +16,33 @@
import { IconComponent, RouteRef } from '@backstage/core-plugin-api';
import { createSchemaFromZod } from '../schema/createSchemaFromZod';
-import { coreExtensionData, createExtension } from '../wiring';
+import {
+ AnyExtensionInputMap,
+ ExtensionInputValues,
+ coreExtensionData,
+ createExtension,
+} from '../wiring';
+import { Expand } from '../wiring/createExtension';
+import { Suspense, lazy } from 'react';
+import React from 'react';
/**
* Helper for creating extensions for a nav item.
* @public
*/
-export function createNavItemExtension(options: {
+export function createNavItemExtension<
+ TInputs extends AnyExtensionInputMap,
+>(options: {
id: string;
routeRef: RouteRef;
title: string;
icon: IconComponent;
+ inputs?: TInputs;
+ group?: (options: {
+ inputs: Expand>;
+ }) => Promise;
}) {
- const { id, routeRef, title, icon } = options;
+ const { id, routeRef, title, icon, group } = options;
return createExtension({
id,
at: 'core.nav/items',
@@ -37,15 +51,28 @@ export function createNavItemExtension(options: {
title: z.string().default(title),
}),
),
+ inputs: options.inputs,
output: {
navTarget: coreExtensionData.navTarget,
},
- factory: ({ bind, config }) => {
+ factory: ({ bind, config, inputs }) => {
+ const Group = group
+ ? (lazy(() =>
+ group({ inputs }).then(element => ({
+ default: () => element,
+ })),
+ ) as unknown as () => JSX.Element)
+ : undefined;
bind({
navTarget: {
title: config.title,
icon,
routeRef,
+ group: Group ? (
+
+
+
+ ) : undefined,
},
});
},
diff --git a/packages/frontend-plugin-api/src/wiring/coreExtensionData.ts b/packages/frontend-plugin-api/src/wiring/coreExtensionData.ts
index 079d5bcb18..d03513677d 100644
--- a/packages/frontend-plugin-api/src/wiring/coreExtensionData.ts
+++ b/packages/frontend-plugin-api/src/wiring/coreExtensionData.ts
@@ -27,6 +27,7 @@ export type NavTarget = {
title: string;
icon: IconComponent;
routeRef: RouteRef<{}>;
+ group?: JSX.Element;
};
/** @public */