Initial SvelteKit frontend port of windwiderstand.de
Full parity with Astro site: content rows, post/tag routes, pagination, event badges + OSM map, comments, Live-Search via /api/search-index, CMS image proxy, RSS, sitemap. Deploy: Dockerfile + docker-compose.prod.yml + Gitea Actions workflow to build + push to git.pm86.de registry and ssh-deploy to Contabo.
This commit is contained in:
@@ -0,0 +1,163 @@
|
||||
/**
|
||||
* Layout für Content-Blöcke (z. B. Markdown): Grid-Spalten (1–12) und Abstand.
|
||||
* Entspricht component_layout im CMS (desktop/tablet/mobile = Breite in 12tel, spaceBottom = rem).
|
||||
*/
|
||||
|
||||
export type BlockLayout = {
|
||||
/** Breite auf Desktop (1–12), z. B. "8" = 8/12. */
|
||||
desktop?:
|
||||
| "1"
|
||||
| "2"
|
||||
| "3"
|
||||
| "4"
|
||||
| "5"
|
||||
| "6"
|
||||
| "7"
|
||||
| "8"
|
||||
| "9"
|
||||
| "10"
|
||||
| "11"
|
||||
| "12";
|
||||
/** Breite auf Tablet (1–12). */
|
||||
tablet?:
|
||||
| "1"
|
||||
| "2"
|
||||
| "3"
|
||||
| "4"
|
||||
| "5"
|
||||
| "6"
|
||||
| "7"
|
||||
| "8"
|
||||
| "9"
|
||||
| "10"
|
||||
| "11"
|
||||
| "12";
|
||||
/** Breite auf Mobile (1–12), Default 12. */
|
||||
mobile?:
|
||||
| "1"
|
||||
| "2"
|
||||
| "3"
|
||||
| "4"
|
||||
| "5"
|
||||
| "6"
|
||||
| "7"
|
||||
| "8"
|
||||
| "9"
|
||||
| "10"
|
||||
| "11"
|
||||
| "12";
|
||||
/** Abstand nach unten (rem): 0, 0.5, 1, 1.5, 2. */
|
||||
spaceBottom?: 0 | 0.5 | 1 | 1.5 | 2;
|
||||
/** true = Block fullwidth aus dem Grid ausbrechen (viewport-breit). */
|
||||
breakout?: boolean;
|
||||
};
|
||||
|
||||
const COL_SPAN: Record<string, string> = {
|
||||
"1": "col-span-1",
|
||||
"2": "col-span-2",
|
||||
"3": "col-span-3",
|
||||
"4": "col-span-4",
|
||||
"5": "col-span-5",
|
||||
"6": "col-span-6",
|
||||
"7": "col-span-7",
|
||||
"8": "col-span-8",
|
||||
"9": "col-span-9",
|
||||
"10": "col-span-10",
|
||||
"11": "col-span-11",
|
||||
"12": "col-span-12",
|
||||
};
|
||||
|
||||
const MD_COL_SPAN: Record<string, string> = {
|
||||
"1": "md:col-span-1",
|
||||
"2": "md:col-span-2",
|
||||
"3": "md:col-span-3",
|
||||
"4": "md:col-span-4",
|
||||
"5": "md:col-span-5",
|
||||
"6": "md:col-span-6",
|
||||
"7": "md:col-span-7",
|
||||
"8": "md:col-span-8",
|
||||
"9": "md:col-span-9",
|
||||
"10": "md:col-span-10",
|
||||
"11": "md:col-span-11",
|
||||
"12": "md:col-span-12",
|
||||
};
|
||||
|
||||
const LG_COL_SPAN: Record<string, string> = {
|
||||
"1": "lg:col-span-1",
|
||||
"2": "lg:col-span-2",
|
||||
"3": "lg:col-span-3",
|
||||
"4": "lg:col-span-4",
|
||||
"5": "lg:col-span-5",
|
||||
"6": "lg:col-span-6",
|
||||
"7": "lg:col-span-7",
|
||||
"8": "lg:col-span-8",
|
||||
"9": "lg:col-span-9",
|
||||
"10": "lg:col-span-10",
|
||||
"11": "lg:col-span-11",
|
||||
"12": "lg:col-span-12",
|
||||
};
|
||||
|
||||
const SPACE_BOTTOM: Record<number, string> = {
|
||||
0: "mb-0",
|
||||
0.5: "mb-2", // 0.5rem
|
||||
1: "mb-4", // 1rem
|
||||
1.5: "mb-6", // 1.5rem
|
||||
2: "mb-8", // 2rem
|
||||
};
|
||||
|
||||
/**
|
||||
* Gibt Tailwind-Klassen für das Block-Layout zurück (12-Spalten-Grid + Abstand).
|
||||
* Parent muss grid grid-cols-12 haben.
|
||||
*/
|
||||
/**
|
||||
* Gibt Tailwind-Klassen für den Block-Inhalt zurück.
|
||||
* Bei breakout: true nur w-full + Abstand (Spalten/Wrapper kommen von außen).
|
||||
*/
|
||||
export function getBlockLayoutClasses(
|
||||
layout: BlockLayout | undefined | null,
|
||||
): string {
|
||||
if (!layout || typeof layout !== "object") {
|
||||
return "col-span-12 mb-4";
|
||||
}
|
||||
const breakout = layout.breakout === true;
|
||||
const sb =
|
||||
typeof layout.spaceBottom === "number"
|
||||
? layout.spaceBottom
|
||||
: Number(layout.spaceBottom);
|
||||
const spaceClass = SPACE_BOTTOM[sb as keyof typeof SPACE_BOTTOM] ?? "mb-4";
|
||||
|
||||
if (breakout) {
|
||||
return "w-full";
|
||||
}
|
||||
|
||||
const mobile = String(layout.mobile ?? "12");
|
||||
const tablet = layout.tablet != null ? String(layout.tablet) : undefined;
|
||||
const desktop = layout.desktop != null ? String(layout.desktop) : undefined;
|
||||
|
||||
const parts: string[] = [
|
||||
COL_SPAN[mobile] ?? "col-span-12",
|
||||
tablet ? (MD_COL_SPAN[tablet] ?? "") : "",
|
||||
desktop ? (LG_COL_SPAN[desktop] ?? "") : "",
|
||||
spaceClass,
|
||||
];
|
||||
return parts.filter(Boolean).join(" ");
|
||||
}
|
||||
|
||||
/** Tailwind-Klasse für spaceBottom (z. B. am Breakout-Wrapper). */
|
||||
export function getSpaceBottomClass(
|
||||
layout: BlockLayout | undefined | null,
|
||||
): string {
|
||||
if (!layout || typeof layout !== "object") return "mb-4";
|
||||
const sb =
|
||||
typeof layout.spaceBottom === "number"
|
||||
? layout.spaceBottom
|
||||
: Number(layout.spaceBottom);
|
||||
return SPACE_BOTTOM[sb as keyof typeof SPACE_BOTTOM] ?? "mb-4";
|
||||
}
|
||||
|
||||
/** Prüft, ob das Layout breakout (fullwidth) haben soll. */
|
||||
export function isBlockLayoutBreakout(
|
||||
layout: BlockLayout | undefined | null,
|
||||
): boolean {
|
||||
return !!(layout && typeof layout === "object" && layout.breakout === true);
|
||||
}
|
||||
Reference in New Issue
Block a user