feat: add interactive homepage layout lab

This commit is contained in:
Friday authored and Nuno C. committed 2026-08-17 20:19:02 +01:00
1 parent af0e11171c
commit e62da9e2d1
4 files changed
+97

No files matched your search

+26
View File
@@ -26,6 +26,32 @@ window.addEventListener("DOMContentLoaded", (event) => {
);
});
function initLayoutLab() {
const lab = document.querySelector("[data-layout-lab]");
if (!lab) return;
const buttons = lab.querySelectorAll("[data-layout-preview-button]");
const panels = lab.querySelectorAll("[data-layout-preview-panel]");
const activate = (layout) => {
buttons.forEach((button) => {
const active = button.dataset.layoutPreviewButton === layout;
button.setAttribute("aria-selected", String(active));
button.classList.toggle("bg-primary-600", active);
button.classList.toggle("text-white", active);
button.classList.toggle("dark:border-primary-600", active);
});
panels.forEach((panel) => {
panel.hidden = panel.dataset.layoutPreviewPanel !== layout;
});
};
buttons.forEach((button) => {
button.addEventListener("click", () => activate(button.dataset.layoutPreviewButton));
});
}
window.addEventListener("DOMContentLoaded", initLayoutLab);
var list_config = ["CardViewProse", "CardViewScreenWidth", "NormalView"];
var titles = {
+13
View File
@@ -0,0 +1,13 @@
---
title: "Homepage layout lab"
description: "Try Blowfish's built-in homepage layouts without changing your site configuration."
type: "layout-lab"
---
{{< lead >}}
Choose a layout below to preview how the same content behaves across Blowfish's built-in homepage patterns.
{{< /lead >}}
{{< alert "circle-info" >}}
This is an example-site playground. Your own site selects a homepage layout with `homepage.layout` in `params.toml`.
{{< /alert >}}
+33
View File
@@ -0,0 +1,33 @@
{{ define "main" }}
{{ $jsHome := resources.Get "js/home.js" | resources.Minify | resources.Fingerprint (.Site.Params.fingerprintAlgorithm | default "sha512") }}
<section class="mx-auto max-w-4xl py-10 text-center">
<p class="text-sm font-bold uppercase tracking-[0.18em] text-primary-600 dark:text-primary-400">Interactive preview</p>
<h1 class="mt-2 text-4xl font-black tracking-tight text-neutral-950 dark:text-white">{{ .Title }}</h1>
<div class="prose mx-auto mt-5 dark:prose-invert">{{ .Content }}</div>
</section>
<section data-layout-lab class="mb-14">
<div class="not-prose mb-8 flex flex-wrap justify-center gap-2" role="tablist" aria-label="Homepage layouts">
{{ range $index, $layout := slice "landing" "background" "hero" "profile" "page" "card" }}
<button
type="button"
class="rounded-full border border-neutral-300 px-4 py-2 text-sm font-bold text-neutral-700 transition hover:border-primary-400 hover:text-primary-600 dark:border-neutral-700 dark:text-neutral-200 dark:hover:text-primary-400 {{ if eq $index 0 }}bg-primary-600 text-white hover:bg-primary-500 hover:text-white dark:border-primary-600{{ end }}"
data-layout-preview-button="{{ $layout }}"
role="tab"
aria-selected="{{ cond (eq $index 0) `true` `false` }}">
{{ $layout | title }}
</button>
{{ end }}
</div>
<div class="rounded-3xl border border-neutral-200 bg-neutral/40 p-4 shadow-sm dark:border-neutral-800 dark:bg-neutral-900/30 sm:p-8">
{{ range $index, $layout := slice "landing" "background" "hero" "profile" "page" "card" }}
<div data-layout-preview-panel="{{ $layout }}" role="tabpanel"{{ if ne $index 0 }} hidden{{ end }}>
{{ partial (printf "home/%s.html" $layout) $ }}
</div>
{{ end }}
</div>
</section>
<script defer type="text/javascript" src="{{ $jsHome.RelPermalink }}" integrity="{{ $jsHome.Data.Integrity }}"></script>
{{ end }}