feat: unify layout slot architecture - make header/footer configurable positions, footer as array, add defaultPosition fallback, add tests, update docs
This commit is contained in:
@@ -0,0 +1,86 @@
|
||||
import test, { describe } from "node:test"
|
||||
import assert from "node:assert"
|
||||
import { resolveLayout } from "./dispatcher"
|
||||
import { QuartzPageTypePluginInstance } from "../types"
|
||||
import { QuartzComponent } from "../../components/types"
|
||||
|
||||
const StubA: QuartzComponent = (() => null) as unknown as QuartzComponent
|
||||
const StubB: QuartzComponent = (() => null) as unknown as QuartzComponent
|
||||
const StubHead: QuartzComponent = (() => null) as unknown as QuartzComponent
|
||||
|
||||
function makePageType(
|
||||
overrides: Partial<QuartzPageTypePluginInstance> = {},
|
||||
): QuartzPageTypePluginInstance {
|
||||
return {
|
||||
name: "test-page-type",
|
||||
layout: "content",
|
||||
match: () => true,
|
||||
body: () => (() => null) as unknown as QuartzComponent,
|
||||
...overrides,
|
||||
} as QuartzPageTypePluginInstance
|
||||
}
|
||||
|
||||
describe("resolveLayout", () => {
|
||||
test("footer defaults to [] when sharedDefaults omits footer", () => {
|
||||
const result = resolveLayout(makePageType(), { head: StubHead }, {})
|
||||
assert.deepStrictEqual(result.footer, [])
|
||||
})
|
||||
|
||||
test("header defaults to [] when sharedDefaults omits header", () => {
|
||||
const result = resolveLayout(makePageType(), { head: StubHead }, {})
|
||||
assert.deepStrictEqual(result.header, [])
|
||||
})
|
||||
|
||||
test("footer from sharedDefaults is used when no override", () => {
|
||||
const result = resolveLayout(makePageType(), { head: StubHead, footer: [StubA] }, {})
|
||||
assert.deepStrictEqual(result.footer, [StubA])
|
||||
})
|
||||
|
||||
test("byPageType override replaces footer", () => {
|
||||
const result = resolveLayout(
|
||||
makePageType(),
|
||||
{ head: StubHead, footer: [StubA] },
|
||||
{ content: { footer: [StubB] } },
|
||||
)
|
||||
assert.deepStrictEqual(result.footer, [StubB])
|
||||
})
|
||||
|
||||
test("byPageType override clears footer with []", () => {
|
||||
const result = resolveLayout(
|
||||
makePageType(),
|
||||
{ head: StubHead, footer: [StubA] },
|
||||
{ content: { footer: [] } },
|
||||
)
|
||||
assert.deepStrictEqual(result.footer, [])
|
||||
})
|
||||
|
||||
test("byPageType override clears header with []", () => {
|
||||
const result = resolveLayout(
|
||||
makePageType(),
|
||||
{ head: StubHead, header: [StubA] },
|
||||
{ content: { header: [] } },
|
||||
)
|
||||
assert.deepStrictEqual(result.header, [])
|
||||
})
|
||||
})
|
||||
|
||||
describe("resolveLayout frame resolution", () => {
|
||||
test("config override frame wins over page type frame", () => {
|
||||
const result = resolveLayout(
|
||||
makePageType({ frame: "minimal" }),
|
||||
{ head: StubHead },
|
||||
{ content: { frame: "full-width" } },
|
||||
)
|
||||
assert.strictEqual(result.frame, "full-width")
|
||||
})
|
||||
|
||||
test("page type frame wins when no config override", () => {
|
||||
const result = resolveLayout(makePageType({ frame: "minimal" }), { head: StubHead }, {})
|
||||
assert.strictEqual(result.frame, "minimal")
|
||||
})
|
||||
|
||||
test("defaults to 'default' when no frame specified", () => {
|
||||
const result = resolveLayout(makePageType(), { head: StubHead }, {})
|
||||
assert.strictEqual(result.frame, "default")
|
||||
})
|
||||
})
|
||||
@@ -15,7 +15,8 @@ function getPageTypes(ctx: BuildCtx): QuartzPageTypePluginInstance[] {
|
||||
return (ctx.cfg.plugins.pageTypes ?? []) as unknown as QuartzPageTypePluginInstance[]
|
||||
}
|
||||
|
||||
function resolveLayout(
|
||||
/** @internal Exported for testing only. */
|
||||
export function resolveLayout(
|
||||
pageType: QuartzPageTypePluginInstance,
|
||||
sharedDefaults: Partial<FullPageLayout>,
|
||||
byPageType: Record<string, Partial<FullPageLayout>>,
|
||||
@@ -31,7 +32,7 @@ function resolveLayout(
|
||||
afterBody: overrides.afterBody ?? sharedDefaults.afterBody ?? [],
|
||||
left: overrides.left ?? sharedDefaults.left ?? [],
|
||||
right: overrides.right ?? sharedDefaults.right ?? [],
|
||||
footer: overrides.footer ?? sharedDefaults.footer!,
|
||||
footer: overrides.footer ?? sharedDefaults.footer ?? [],
|
||||
frame,
|
||||
}
|
||||
}
|
||||
@@ -52,7 +53,7 @@ function collectComponents(
|
||||
...layout.afterBody,
|
||||
...layout.left,
|
||||
...layout.right,
|
||||
layout.footer,
|
||||
...layout.footer,
|
||||
]
|
||||
for (const c of all) {
|
||||
if (c) seen.add(c)
|
||||
|
||||
Reference in New Issue
Block a user