feat(frontend-app-api): add support for sidebar group

Signed-off-by: Camila Belo <camilaibs@gmail.com>
This commit is contained in:
Camila Belo
2023-09-27 09:38:24 +02:00
parent 6e9fbc540d
commit 5d92f07ff6
3 changed files with 45 additions and 9 deletions
@@ -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 ? (
<SidebarGroup to={to} icon={<Icon />} label={title}>
{group}
</SidebarGroup>
) : (
<SidebarItem to={to} icon={Icon} text={title} />
);
};
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 <SidebarItem icon={icon} to={to} text={title} />;
};
bind({
element: (
<Sidebar>
@@ -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<ExtensionInputValues<TInputs>>;
}) => Promise<JSX.Element>;
}) {
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 ? (
<Suspense fallback="...">
<Group />
</Suspense>
) : undefined,
},
});
},
@@ -27,6 +27,7 @@ export type NavTarget = {
title: string;
icon: IconComponent;
routeRef: RouteRef<{}>;
group?: JSX.Element;
};
/** @public */