import { getLocalizedString } from "@olenbetong/appframe-core"; import { Fragment, type RefObject } from "react"; import { AppMenuColorScheme } from "./AppMenuColorScheme.js"; import { countItems, groupLabel, type Selection, toRailSections } from "./menuEntries.js"; import type { AppMenuCategory } from "./types.js"; import { useRovingTabIndex } from "./useRovingTabIndex.js"; export type AppMenuRailProps = { searchRef: RefObject; search: string; onSearchChange: (value: string) => void; /** App groups, in the order they are listed. */ groups: { key: string; count: number }[]; /** Number of apps matching the search, shown next to "All applications". */ appCount: number; /** Extra link categories, listed after the app groups. */ categories: AppMenuCategory[]; selection: Selection; onSelect: (selection: Selection) => void; }; /** * The app menu's left rail: the local search field, the app groups and any * extra link categories. * * The rail is a single tab stop; the arrow keys move focus between the buttons. */ export function AppMenuRail({ searchRef, search, onSearchChange, groups, appCount, categories, selection, onSelect, }: AppMenuRailProps) { // "All applications", then the app groups, then the categories. let roving = useRovingTabIndex(groups.length + 1 + categories.length); let railSections = toRailSections(categories); let categoryIndex = groups.length; function isSelected(next: NonNullable) { if (selection === null) return false; if (next.type === "group") return selection.type === "group" && selection.key === next.key; return selection.type === "category" && selection.id === next.id; } return (
onSearchChange(event.target.value)} placeholder={getLocalizedString("Search applications")} aria-label={getLocalizedString("Search applications")} autoComplete="off" />
); }