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:
@@ -412,13 +412,13 @@ export const MyFrame: PageFrame = {
|
||||
grid-template-areas: "center";
|
||||
}
|
||||
`,
|
||||
render({ componentData, pageBody: Content, footer: Footer }: PageFrameProps): unknown {
|
||||
render({ componentData, pageBody: Content, footer: Footers }: PageFrameProps): unknown {
|
||||
const renderSlot = (C: (props: typeof componentData) => unknown): ComponentChildren =>
|
||||
C(componentData) as ComponentChildren
|
||||
return (
|
||||
<div class="center">
|
||||
{(Content as any)(componentData)}
|
||||
{(Footer as any)(componentData)}
|
||||
{Footers.map((Footer) => (Footer as any)(componentData))}
|
||||
</div>
|
||||
)
|
||||
},
|
||||
@@ -428,7 +428,7 @@ export const MyFrame: PageFrame = {
|
||||
Key requirements:
|
||||
|
||||
- `name`: A unique string identifier. This is what page types and YAML config reference.
|
||||
- `render()`: Receives all layout slots (header, sidebars, content, footer) and returns JSX for the inner page structure.
|
||||
- `render()`: Receives all layout slots (header, sidebars, content, footer) and returns JSX for the inner page structure. Note that `footer` is a `QuartzComponent[]` (an array) — frames should iterate over it with `.map()` to render all footer components.
|
||||
- `css` (optional): Frame-specific CSS. Scope it with `.page[data-frame="my-frame"]` selectors to avoid conflicts.
|
||||
|
||||
**2. Re-export the frame:**
|
||||
|
||||
@@ -28,6 +28,42 @@ npx quartz plugin install --latest
|
||||
|
||||
See the [[upgrade|CLI reference for upgrade]] for more details on available flags.
|
||||
|
||||
### Layout System Changes
|
||||
|
||||
The `footer` layout slot is now an array of components, consistent with other layout slots like `header`, `left`, and `right`. Additionally, `header` and `footer` are now configurable layout positions — plugins can declare `layout: { position: header }` or `layout: { position: footer }` in their YAML config.
|
||||
|
||||
**If you override layouts in `quartz.ts`**, update any `footer` assignments to use arrays:
|
||||
|
||||
```ts title="quartz.ts"
|
||||
// Before
|
||||
export const layout = await loadQuartzLayout({
|
||||
defaults: { footer: MyFooterComponent },
|
||||
})
|
||||
|
||||
// After
|
||||
export const layout = await loadQuartzLayout({
|
||||
defaults: { footer: [MyFooterComponent] },
|
||||
})
|
||||
```
|
||||
|
||||
**If you have a custom page frame**, update the `render` function to iterate the footer array:
|
||||
|
||||
```tsx
|
||||
// Before
|
||||
render({ footer: Footer, ...rest }: PageFrameProps) {
|
||||
return <Footer {...componentData} />
|
||||
}
|
||||
|
||||
// After
|
||||
render({ footer, ...rest }: PageFrameProps) {
|
||||
return footer.map((F) => <F {...componentData} />)
|
||||
}
|
||||
```
|
||||
|
||||
Both changes are caught by TypeScript at compile time — running `npx quartz build` will show the error.
|
||||
|
||||
No changes are needed for `quartz.config.yaml` — the YAML format is unchanged.
|
||||
|
||||
### Cleaning Up Unused Plugins
|
||||
|
||||
If you've removed plugins from your configuration during an upgrade, you can clean up the leftover files:
|
||||
|
||||
+10
-2
@@ -20,7 +20,7 @@ export interface FullPageLayout {
|
||||
afterBody: QuartzComponent[] // laid out vertically
|
||||
left: QuartzComponent[] // vertical on desktop and tablet, horizontal on mobile
|
||||
right: QuartzComponent[] // vertical on desktop, horizontal on tablet and mobile
|
||||
footer: QuartzComponent // single component
|
||||
footer: QuartzComponent[] // laid out vertically
|
||||
}
|
||||
```
|
||||
|
||||
@@ -36,7 +36,7 @@ These correspond to following parts of the page:
|
||||
> There are two additional layout fields that are _not_ shown in the above diagram.
|
||||
>
|
||||
> 1. `head` is a single component that renders the `<head>` [tag](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/head) in the HTML. This doesn't appear visually on the page and is only is responsible for metadata about the document like the tab title, scripts, and styles.
|
||||
> 2. `header` is a set of components that are laid out horizontally and appears _before_ the `beforeBody` section. This enables you to replicate the old Quartz 3 header bar where the title, search bar, and dark mode toggle. By default, Quartz doesn't place any components in the `header`.
|
||||
> 2. `header` is a set of components that are laid out horizontally and appears _before_ the `beforeBody` section. You can place components in the header by setting `layout.position: header` in your plugin configuration. This enables layouts similar to Quartz 3's header bar with title, search bar, and dark mode toggle.
|
||||
|
||||
Layout components are configured in the `layout` section of `quartz.config.yaml`. Plugins declare their position and priority, and the layout system arranges them automatically:
|
||||
|
||||
@@ -77,12 +77,20 @@ plugins:
|
||||
layout:
|
||||
position: beforeBody
|
||||
priority: 30
|
||||
- source: github:quartz-community/darkmode
|
||||
enabled: true
|
||||
layout:
|
||||
position: header
|
||||
priority: 10
|
||||
- source: github:quartz-community/footer
|
||||
enabled: true
|
||||
options:
|
||||
links:
|
||||
GitHub: https://github.com/jackyzha0/quartz
|
||||
Discord Community: https://discord.gg/cRFFHYye7t
|
||||
layout:
|
||||
position: footer
|
||||
priority: 50
|
||||
|
||||
layout:
|
||||
groups:
|
||||
|
||||
Reference in New Issue
Block a user