recipes/web/comp/page_layout.ts

68 lines
1.9 KiB
TypeScript

import { AnyNode, Attrs, E, Elem } from "ren/node.ts";
import { classNames } from "ren/attrs.ts";
import { Context, getLangHref, iterLangs, Lang } from "../context.ts";
export function PageLayout(ctx: Context, children: AnyNode[]): Elem {
return E("div", { id: "main" }, [
Header(ctx),
E("div", classNames("content"), children),
Footer(ctx),
]);
}
export function Header(ctx: Context): AnyNode {
return E("header", classNames("header gap-v-1x5"), [
E("div", classNames("content-width"), [HeaderNav(ctx)]),
]);
}
export function HeaderNav(ctx: Context): AnyNode {
return E("nav", classNames("main-menu"), [
Link(ctx.tr.Home, navLink("/", ctx)),
Link(ctx.tr.Recipes, navLink("/recipes", ctx)),
Link(ctx.tr.Ingredients, navLink("/ingredients", ctx)),
]);
}
function navLink(lhref: string, ctx?: Context): Attrs {
const attrs: Attrs = { lhref };
if (ctx?.locPath === lhref) attrs["aria-current"] = "true";
return attrs;
}
export function Footer(ctx: Context): AnyNode {
return E("footer", classNames("footer"), [
E("div", classNames("content-width row-sta-bet"), [
Link(ctx.tr.Source_code, {
target: "_blank",
href: "https://notabug.org/pleshevskiy/recipes",
rel: "external nofollow noopener noreferrer",
}),
ChangeLang(ctx),
]),
]);
}
export function Link(text: string, attrs: Attrs | Attrs[]): AnyNode {
return E("a", attrs, text);
}
export function ChangeLang(ctx: Context): AnyNode {
const dropdownId = "change_langs";
return E("div", classNames("dropdown"), [
E("input", { id: dropdownId, type: "checkbox" }),
E("label", { for: dropdownId }, ctx.lang),
E(
"ul",
[],
iterLangs().filter((l) => l !== ctx.lang).map((l) =>
ChangeLangBtn(ctx, l)
),
),
]);
}
export function ChangeLangBtn(ctx: Context, lang: Lang): AnyNode {
return E("a", { "href": getLangHref(lang, ctx.locPath) }, lang);
}