Files
homarr/apps/nextjs/src/components/layout/navigation.tsx
T

83 lines
2.7 KiB
TypeScript

import type { JSX } from "react";
import { AppShellSection, Image, ScrollArea } from "@mantine/core";
import type { TablerIcon, TablerIconProps } from "@homarr/ui";
import type { ClientNavigationLink } from "./navigation-link";
import { CommonNavLink } from "./navigation-link";
import { NavigationPanel } from "./shell";
interface MainNavigationProps {
headerSection?: JSX.Element;
footerSection?: JSX.Element;
links: NavigationLink[];
}
export const MainNavigation = ({ headerSection, footerSection, links }: MainNavigationProps) => {
return (
<NavigationPanel>
{headerSection && <AppShellSection>{headerSection}</AppShellSection>}
<AppShellSection
grow
mt={headerSection ? "md" : undefined}
mb={footerSection ? "md" : undefined}
component={ScrollArea}
>
{links.map((link, index) => {
if (link.hidden) {
return null;
}
const { icon: TablerIcon, iconProps, "data-onboarding-tour-id": tourId, ...props } = link;
const Icon =
typeof TablerIcon === "string" ? (
<Image src={TablerIcon} w={20} h={20} />
) : (
<TablerIcon size={20} stroke={1.5} {...iconProps} />
);
let clientLink: ClientNavigationLink;
if ("items" in props) {
clientLink = {
...props,
"data-onboarding-tour-id": tourId,
items: props.items
.filter((item) => !item.hidden)
.map((item) => {
const { "data-onboarding-tour-id": itemTourId, ...rest } = item;
return {
...rest,
"data-onboarding-tour-id": itemTourId,
icon: <item.icon size={20} stroke={1.5} {...iconProps} />,
};
}),
} as ClientNavigationLink;
} else {
clientLink = { ...props, "data-onboarding-tour-id": tourId } as ClientNavigationLink;
}
return <CommonNavLink key={index} {...clientLink} icon={Icon} />;
})}
</AppShellSection>
{footerSection && <AppShellSection>{footerSection}</AppShellSection>}
</NavigationPanel>
);
};
interface CommonNavigationLinkProps {
label: string;
icon: TablerIcon | string;
iconProps?: TablerIconProps;
hidden?: boolean;
"data-onboarding-tour-id"?: string;
}
interface NavigationLinkHref extends CommonNavigationLinkProps {
href: string;
external?: boolean;
exact?: boolean;
}
interface NavigationLinkWithItems extends CommonNavigationLinkProps {
items: NavigationLinkHref[];
}
export type NavigationLink = NavigationLinkHref | NavigationLinkWithItems;