import { AppMenuFavoriteButton } from "./AppMenuFavoriteButton.js";
import type { AppMenuLink, AppMenuLinkGroup } from "./types.js";
import { useRovingTabIndex } from "./useRovingTabIndex.js";
export type AppMenuListProps = {
groups: AppMenuLinkGroup[];
/** Total number of links across all groups; the roving tab index size. */
itemCount: number;
/** Called when an entry that doesn't opt out with `keepOpen` is activated. */
onClose: () => void;
/** Without a handler no favorite toggles are rendered. */
onToggleFavorite?: (id: string, favorite: boolean) => void;
};
/**
* The app menu's right hand pane: the selected category's links, laid out as
* titled groups of wrapping columns.
*
* The whole list is a single tab stop; the arrow keys move focus between the
* links, following the visual grid.
*/
export function AppMenuList({ groups, itemCount, onClose, onToggleFavorite }: AppMenuListProps) {
let roving = useRovingTabIndex(itemCount, { columns: true });
// Links are numbered across all groups, since they share one roving index.
let itemIndex = -1;
function renderItem(item: AppMenuLink, index: number) {
let props = {
className: "ob-app-menu__link",
...item.attributes,
...roving.getItemProps(index),
};
function activate() {
item.onClick?.();
if (!item.keepOpen) onClose();
}
let link = item.href ? (
{item.label}
) : (
);
// Only app entries carry an id and a favorite state; the fixed category
// links (e.g. the developer tools) can't be favorited.
if (!onToggleFavorite || item.id === undefined || typeof item.isFavorite !== "boolean") return link;
let id = item.id;
let isFavorite = item.isFavorite;
return (
<>
{link}
onToggleFavorite(id, !isFavorite)}
{...roving.getSecondaryProps(index)}
/>
>
);
}
return (