integratedhub/islands/WelcomeBar/NavigationMenu.tsx
2026-02-15 03:00:24 +00:00

97 lines
2.5 KiB
TypeScript

import {
NavigationGroup,
NavigationItem,
NavigationMenuProps,
} from "./welcome-types.ts";
import {
getNavigationGroups,
isNavigationItemActive,
} from "./navigationConfig.ts";
/**
* NavigationMenu Component
* Native-rendered dropdown content for <details> menu.
*/
export default function NavigationMenu(
{ isLoggedIn, currentRoute, navigationGroups, serverCalendarPath }:
NavigationMenuProps,
) {
function getItemStateClass(item: NavigationItem): string {
if (item.disabled) return "navigation-menu-item--disabled";
if (item.path === "/auth/logout") return "navigation-menu-item--logout";
if (item.path === "/auth/login") return "navigation-menu-item--login";
return "navigation-menu-item--default";
}
function renderNavigationItem(item: NavigationItem) {
if (!item.isForm && isNavigationItemActive(item, currentRoute)) {
return null;
}
const itemClass = `navigation-menu-item ${getItemStateClass(item)}`;
if (item.isForm && item.formAction) {
return (
<form method={item.formMethod || "post"} action={item.formAction}>
<button
type="submit"
onClick={item.onClick}
class={itemClass}
role="menuitem"
disabled={item.disabled}
>
{item.label}
</button>
</form>
);
}
return (
<a
href={item.path}
class={itemClass}
role="menuitem"
aria-disabled={item.disabled}
>
{item.label}
</a>
);
}
function renderNavigationGroup(group: NavigationGroup) {
if (group.items.length === 0) return null;
return (
<div key={group.id} class="navigation-menu-group">
{group.id !== "auth" && <div class="navigation-menu-separator" />}
<p class="navigation-menu-group-label">{group.label}</p>
{group.items.map(renderNavigationItem)}
</div>
);
}
const groups = getNavigationGroups(
isLoggedIn,
currentRoute,
navigationGroups,
serverCalendarPath,
);
if (groups.length === 0) {
return (
<div class="navigation-menu" role="menu" aria-label="Navigation menu">
<div class="navigation-menu-group">
<p class="navigation-menu-group-label">Navigation</p>
<p class="navigation-menu-empty">No actions available</p>
</div>
</div>
);
}
return (
<div class="navigation-menu" role="menu" aria-label="Navigation menu">
{groups.map(renderNavigationGroup)}
</div>
);
}