39 lines
1.2 KiB
TypeScript
39 lines
1.2 KiB
TypeScript
|
import { SITE_DEFAULT_META, SITE_TITLE } from "./constants.js";
|
||
|
import { JSX } from "preact/jsx-runtime";
|
||
|
|
||
|
type Props = {
|
||
|
title?: string;
|
||
|
meta?: { [name: string]: string };
|
||
|
asset(path: string): string;
|
||
|
} & ({ content: string } | { Content(): JSX.Element });
|
||
|
|
||
|
export default (props: Props) => {
|
||
|
const metaTags = Object.entries(Object.assign({}, SITE_DEFAULT_META, props.meta || {})).map(
|
||
|
([name, value]) => <meta name={name} value={value} />,
|
||
|
);
|
||
|
|
||
|
return (
|
||
|
<html lang="en">
|
||
|
<head>
|
||
|
<meta charset="utf-8" />
|
||
|
<title
|
||
|
dangerouslySetInnerHTML={{
|
||
|
__html: [props.title, SITE_TITLE].filter(Boolean).join(" – "),
|
||
|
}}
|
||
|
/>
|
||
|
{metaTags}
|
||
|
<link rel="stylesheet" type="text/css" href={props.asset("index.css")} />
|
||
|
</head>
|
||
|
<body>
|
||
|
{"Content" in props ? (
|
||
|
<div class="main">
|
||
|
<props.Content />
|
||
|
</div>
|
||
|
) : (
|
||
|
<div class="main" dangerouslySetInnerHTML={{ __html: props.content }} />
|
||
|
)}
|
||
|
</body>
|
||
|
</html>
|
||
|
);
|
||
|
};
|