generic quartz component for layout
This commit is contained in:
		@@ -4,17 +4,16 @@ import { EmitCallback, QuartzEmitterPlugin } from "../types"
 | 
			
		||||
import { ProcessedContent } from "../vfile"
 | 
			
		||||
import { Fragment, jsx, jsxs } from 'preact/jsx-runtime'
 | 
			
		||||
import { render } from "preact-render-to-string"
 | 
			
		||||
import { HeadProps } from "../../components/Head"
 | 
			
		||||
import { GlobalConfiguration } from "../../cfg"
 | 
			
		||||
import { HeaderProps } from "../../components/Header"
 | 
			
		||||
import { QuartzComponent } from "../../components/types"
 | 
			
		||||
import { resolveToRoot } from "../../path"
 | 
			
		||||
import { BodyProps } from "../../components/Body"
 | 
			
		||||
import Header from "../../components/Header"
 | 
			
		||||
import { QuartzComponentProps } from "../../components/types"
 | 
			
		||||
 | 
			
		||||
interface Options {
 | 
			
		||||
  Head: QuartzComponent<HeadProps>
 | 
			
		||||
  Header: QuartzComponent<HeaderProps>
 | 
			
		||||
  Body: QuartzComponent<BodyProps>
 | 
			
		||||
  head: QuartzComponent
 | 
			
		||||
  header: QuartzComponent[],
 | 
			
		||||
  body: QuartzComponent
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export class ContentPage extends QuartzEmitterPlugin {
 | 
			
		||||
@@ -26,21 +25,21 @@ export class ContentPage extends QuartzEmitterPlugin {
 | 
			
		||||
    this.opts = opts
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  getQuartzComponents(): QuartzComponent<any>[] {
 | 
			
		||||
    return [...Object.values(this.opts)]
 | 
			
		||||
  getQuartzComponents(): QuartzComponent[] {
 | 
			
		||||
    return [this.opts.head, Header, ...this.opts.header, this.opts.body]
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  async emit(cfg: GlobalConfiguration, content: ProcessedContent[], resources: StaticResources, emit: EmitCallback): Promise<string[]> {
 | 
			
		||||
    const fps: string[] = []
 | 
			
		||||
 | 
			
		||||
    const { Head, Header, Body } = this.opts
 | 
			
		||||
    const { head: Head, header, body: Body } = this.opts
 | 
			
		||||
    for (const [tree, file] of content) {
 | 
			
		||||
      // @ts-ignore (preact makes it angry)
 | 
			
		||||
      const content = toJsxRuntime(tree, { Fragment, jsx, jsxs, elementAttributeNameCase: 'html' })
 | 
			
		||||
 | 
			
		||||
      const baseDir = resolveToRoot(file.data.slug!)
 | 
			
		||||
      const pageResources: StaticResources = {
 | 
			
		||||
        css: [baseDir + "/index.css", ...resources.css,],
 | 
			
		||||
        css: [baseDir + "/index.css", ...resources.css],
 | 
			
		||||
        js: [
 | 
			
		||||
          { src: baseDir + "/prescript.js", loadTime: "beforeDOMReady" },
 | 
			
		||||
          ...resources.js,
 | 
			
		||||
@@ -48,17 +47,23 @@ export class ContentPage extends QuartzEmitterPlugin {
 | 
			
		||||
        ]
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      const title = file.data.frontmatter?.title
 | 
			
		||||
      const componentData: QuartzComponentProps = {
 | 
			
		||||
        fileData: file.data,
 | 
			
		||||
        externalResources: pageResources,
 | 
			
		||||
        cfg,
 | 
			
		||||
        children: [content]
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      const doc = <html>
 | 
			
		||||
        <Head
 | 
			
		||||
          title={title ?? "Untitled"}
 | 
			
		||||
          description={file.data.description ?? "No description provided"}
 | 
			
		||||
          slug={file.data.slug!}
 | 
			
		||||
          externalResources={pageResources} />
 | 
			
		||||
        <Head {...componentData} />
 | 
			
		||||
        <body>
 | 
			
		||||
          <div id="quartz-root" class="page">
 | 
			
		||||
            <Header title={cfg.siteTitle} slug={file.data.slug!} />
 | 
			
		||||
            <Body title={file.data.slug === "index" ? undefined : title}>{content}</Body>
 | 
			
		||||
            <Header {...componentData} >
 | 
			
		||||
              {header.map(HeaderComponent => <HeaderComponent {...componentData}/>)}
 | 
			
		||||
            </Header>
 | 
			
		||||
            <Body {...componentData}>
 | 
			
		||||
              {content}
 | 
			
		||||
            </Body>
 | 
			
		||||
          </div>
 | 
			
		||||
        </body>
 | 
			
		||||
        {pageResources.js.filter(resource => resource.loadTime === "afterDOMReady").map(resource => <script key={resource.src} {...resource} />)}
 | 
			
		||||
 
 | 
			
		||||
@@ -17,7 +17,7 @@ function joinScripts(scripts: string[]): string {
 | 
			
		||||
 | 
			
		||||
export function emitComponentResources(cfg: GlobalConfiguration, resources: StaticResources, plugins: PluginTypes, emit: EmitCallback) {
 | 
			
		||||
  const fps: string[] = []
 | 
			
		||||
  const allComponents: Set<QuartzComponent<any>> = new Set()
 | 
			
		||||
  const allComponents: Set<QuartzComponent> = new Set()
 | 
			
		||||
  for (const emitter of plugins.emitters) {
 | 
			
		||||
    const components = emitter.getQuartzComponents()
 | 
			
		||||
    for (const component of components) {
 | 
			
		||||
 
 | 
			
		||||
@@ -29,7 +29,9 @@ export class Description extends QuartzTransformerPlugin {
 | 
			
		||||
      () => {
 | 
			
		||||
        return async (tree: HTMLRoot, file) => {
 | 
			
		||||
          const frontMatterDescription = file.data.frontmatter?.description
 | 
			
		||||
          const desc = frontMatterDescription ?? toString(tree)
 | 
			
		||||
          const text = toString(tree)
 | 
			
		||||
 | 
			
		||||
          const desc = frontMatterDescription ?? text
 | 
			
		||||
          const sentences = desc.replace(/\s+/g, ' ').split('.')
 | 
			
		||||
          let finalDesc = ""
 | 
			
		||||
          let sentenceIdx = 0
 | 
			
		||||
@@ -40,6 +42,7 @@ export class Description extends QuartzTransformerPlugin {
 | 
			
		||||
          }
 | 
			
		||||
 | 
			
		||||
          file.data.description = finalDesc
 | 
			
		||||
          file.data.text = text
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    ]
 | 
			
		||||
@@ -49,6 +52,7 @@ export class Description extends QuartzTransformerPlugin {
 | 
			
		||||
declare module 'vfile' {
 | 
			
		||||
  interface DataMap {
 | 
			
		||||
    description: string
 | 
			
		||||
    text: string
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -26,7 +26,7 @@ export type EmitCallback = (data: EmitOptions) => Promise<string>
 | 
			
		||||
export abstract class QuartzEmitterPlugin {
 | 
			
		||||
  abstract name: string
 | 
			
		||||
  abstract emit(cfg: GlobalConfiguration, content: ProcessedContent[], resources: StaticResources, emitCallback: EmitCallback): Promise<string[]>
 | 
			
		||||
  abstract getQuartzComponents(): QuartzComponent<any>[]
 | 
			
		||||
  abstract getQuartzComponents(): QuartzComponent[]
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export interface PluginTypes {
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user