66 lines
1.9 KiB
TypeScript
66 lines
1.9 KiB
TypeScript
import { usePlatformLanguage } from "../i18n/LanguageContext";
|
|
|
|
export type ModuleSubnavItem<T extends string> = {
|
|
id: T;
|
|
label: string;
|
|
subtle?: boolean;
|
|
primary?: boolean;
|
|
};
|
|
|
|
export type ModuleSubnavAction = {
|
|
actionId: string;
|
|
label: string;
|
|
onClick: () => void;
|
|
subtle?: boolean;
|
|
primary?: boolean;
|
|
};
|
|
|
|
export type ModuleSubnavEntry<T extends string> = ModuleSubnavItem<T> | ModuleSubnavAction;
|
|
|
|
export type ModuleSubnavGroup<T extends string> = {
|
|
title?: string;
|
|
items: ModuleSubnavEntry<T>[];
|
|
};
|
|
|
|
function isAction<T extends string>(entry: ModuleSubnavEntry<T>): entry is ModuleSubnavAction {
|
|
return "actionId" in entry;
|
|
}
|
|
|
|
export default function ModuleSubnav<T extends string>({
|
|
active,
|
|
groups,
|
|
onSelect,
|
|
className = ""
|
|
|
|
|
|
|
|
|
|
|
|
}: {active: T;groups: ModuleSubnavGroup<T>[];onSelect: (section: T) => void;className?: string;}) {
|
|
const { translateText } = usePlatformLanguage();
|
|
return (
|
|
<aside className={`section-sidebar ${className}`.trim()}>
|
|
{groups.map((group, groupIndex) =>
|
|
<div className="section-group" key={`${group.title ?? "group"}-${groupIndex}`}>
|
|
{group.title && <div className={`section-title ${groupIndex > 0 ? "section-title-lower" : ""}`.trim()}>{translateText(group.title)}</div>}
|
|
{group.items.map((entry) => {
|
|
const key = isAction(entry) ? entry.actionId : entry.id;
|
|
const activeClass = !isAction(entry) && active === entry.id ? " active" : "";
|
|
const primaryClass = entry.primary ? " section-link-primary" : "";
|
|
const subtleClass = entry.subtle ? " subtle" : "";
|
|
return (
|
|
<button
|
|
key={key}
|
|
className={`section-link${primaryClass}${subtleClass}${activeClass}`}
|
|
onClick={() => isAction(entry) ? entry.onClick() : onSelect(entry.id)}>
|
|
|
|
{translateText(entry.label)}
|
|
</button>);
|
|
|
|
})}
|
|
</div>
|
|
)}
|
|
</aside>);
|
|
|
|
}
|