add config to components
This commit is contained in:
parent
9a1f0b48b4
commit
397f4f7d3a
@ -56,9 +56,9 @@ const config: QuartzConfig = {
|
|||||||
],
|
],
|
||||||
emitters: [
|
emitters: [
|
||||||
Plugin.ContentPage({
|
Plugin.ContentPage({
|
||||||
head: Component.Head,
|
head: Component.Head(),
|
||||||
header: [Component.PageTitle, Component.Spacer, Component.Darkmode],
|
header: [Component.PageTitle(), Component.Spacer(), Component.Darkmode()],
|
||||||
body: [Component.ArticleTitle, Component.ReadingTime, Component.TableOfContents, Component.Content]
|
body: [Component.ArticleTitle(), Component.ReadingTime(), Component.TableOfContents(), Component.Content()]
|
||||||
})
|
})
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { QuartzComponentProps } from "./types"
|
import { QuartzComponentConstructor, QuartzComponentProps } from "./types"
|
||||||
|
|
||||||
export default function ArticleTitle({ fileData }: QuartzComponentProps) {
|
function ArticleTitle({ fileData }: QuartzComponentProps) {
|
||||||
const title = fileData.frontmatter?.title
|
const title = fileData.frontmatter?.title
|
||||||
const displayTitle = fileData.slug === "index" ? undefined : title
|
const displayTitle = fileData.slug === "index" ? undefined : title
|
||||||
if (displayTitle) {
|
if (displayTitle) {
|
||||||
@ -9,3 +9,5 @@ export default function ArticleTitle({ fileData }: QuartzComponentProps) {
|
|||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export default (() => ArticleTitle) satisfies QuartzComponentConstructor
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
import clipboardScript from './scripts/clipboard.inline'
|
import clipboardScript from './scripts/clipboard.inline'
|
||||||
import clipboardStyle from './styles/clipboard.scss'
|
import clipboardStyle from './styles/clipboard.scss'
|
||||||
import { QuartzComponentProps } from "./types"
|
import { QuartzComponentConstructor, QuartzComponentProps } from "./types"
|
||||||
|
|
||||||
export default function Body({ children }: QuartzComponentProps) {
|
function Body({ children }: QuartzComponentProps) {
|
||||||
return <article>
|
return <article>
|
||||||
{children}
|
{children}
|
||||||
</article>
|
</article>
|
||||||
@ -10,3 +10,6 @@ export default function Body({ children }: QuartzComponentProps) {
|
|||||||
|
|
||||||
Body.afterDOMLoaded = clipboardScript
|
Body.afterDOMLoaded = clipboardScript
|
||||||
Body.css = clipboardStyle
|
Body.css = clipboardStyle
|
||||||
|
|
||||||
|
export default (() => Body) satisfies QuartzComponentConstructor
|
||||||
|
|
||||||
|
@ -1,9 +1,11 @@
|
|||||||
import { QuartzComponentProps } from "./types"
|
import { QuartzComponentConstructor, QuartzComponentProps } from "./types"
|
||||||
import { Fragment, jsx, jsxs } from 'preact/jsx-runtime'
|
import { Fragment, jsx, jsxs } from 'preact/jsx-runtime'
|
||||||
import { toJsxRuntime } from "hast-util-to-jsx-runtime"
|
import { toJsxRuntime } from "hast-util-to-jsx-runtime"
|
||||||
|
|
||||||
export default function Content({ tree }: QuartzComponentProps) {
|
function Content({ tree }: QuartzComponentProps) {
|
||||||
// @ts-ignore (preact makes it angry)
|
// @ts-ignore (preact makes it angry)
|
||||||
const content = toJsxRuntime(tree, { Fragment, jsx, jsxs, elementAttributeNameCase: 'html' })
|
const content = toJsxRuntime(tree, { Fragment, jsx, jsxs, elementAttributeNameCase: 'html' })
|
||||||
return content
|
return content
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export default (() => Content) satisfies QuartzComponentConstructor
|
||||||
|
@ -3,8 +3,9 @@
|
|||||||
// see: https://v8.dev/features/modules#defer
|
// see: https://v8.dev/features/modules#defer
|
||||||
import darkmodeScript from "./scripts/darkmode.inline"
|
import darkmodeScript from "./scripts/darkmode.inline"
|
||||||
import styles from './styles/darkmode.scss'
|
import styles from './styles/darkmode.scss'
|
||||||
|
import { QuartzComponentConstructor } from "./types"
|
||||||
|
|
||||||
export default function Darkmode() {
|
function Darkmode() {
|
||||||
return <div class="darkmode">
|
return <div class="darkmode">
|
||||||
<input class="toggle" id="darkmode-toggle" type="checkbox" tabIndex={-1} />
|
<input class="toggle" id="darkmode-toggle" type="checkbox" tabIndex={-1} />
|
||||||
<label id="toggle-label-light" for="darkmode-toggle" tabIndex={-1}>
|
<label id="toggle-label-light" for="darkmode-toggle" tabIndex={-1}>
|
||||||
@ -48,3 +49,5 @@ export default function Darkmode() {
|
|||||||
|
|
||||||
Darkmode.beforeDOMLoaded = darkmodeScript
|
Darkmode.beforeDOMLoaded = darkmodeScript
|
||||||
Darkmode.css = styles
|
Darkmode.css = styles
|
||||||
|
|
||||||
|
export default (() => Darkmode) satisfies QuartzComponentConstructor
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import { resolveToRoot } from "../path"
|
import { resolveToRoot } from "../path"
|
||||||
import { QuartzComponentProps } from "./types"
|
import { QuartzComponentConstructor, QuartzComponentProps } from "./types"
|
||||||
|
|
||||||
export default function Head({ fileData, externalResources }: QuartzComponentProps) {
|
function Head({ fileData, externalResources }: QuartzComponentProps) {
|
||||||
const slug = fileData.slug!
|
const slug = fileData.slug!
|
||||||
const title = fileData.frontmatter?.title ?? "Untitled"
|
const title = fileData.frontmatter?.title ?? "Untitled"
|
||||||
const description = fileData.description ?? "No description provided"
|
const description = fileData.description ?? "No description provided"
|
||||||
@ -9,7 +9,7 @@ export default function Head({ fileData, externalResources }: QuartzComponentPro
|
|||||||
const baseDir = resolveToRoot(slug)
|
const baseDir = resolveToRoot(slug)
|
||||||
const iconPath = baseDir + "/static/icon.png"
|
const iconPath = baseDir + "/static/icon.png"
|
||||||
const ogImagePath = baseDir + "/static/og-image.png"
|
const ogImagePath = baseDir + "/static/og-image.png"
|
||||||
|
|
||||||
return <head>
|
return <head>
|
||||||
<title>{title}</title>
|
<title>{title}</title>
|
||||||
<meta charSet="utf-8" />
|
<meta charSet="utf-8" />
|
||||||
@ -28,3 +28,5 @@ export default function Head({ fileData, externalResources }: QuartzComponentPro
|
|||||||
{js.filter(resource => resource.loadTime === "beforeDOMReady").map(resource => <script key={resource.src} {...resource} spa-preserve />)}
|
{js.filter(resource => resource.loadTime === "beforeDOMReady").map(resource => <script key={resource.src} {...resource} spa-preserve />)}
|
||||||
</head>
|
</head>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export default (() => Head) satisfies QuartzComponentConstructor
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { QuartzComponentProps } from "./types"
|
import { QuartzComponentConstructor, QuartzComponentProps } from "./types"
|
||||||
|
|
||||||
export default function Header({ children }: QuartzComponentProps) {
|
function Header({ children }: QuartzComponentProps) {
|
||||||
return <header>
|
return <header>
|
||||||
{children}
|
{children}
|
||||||
</header>
|
</header>
|
||||||
@ -21,3 +21,5 @@ header > h1 {
|
|||||||
flex: auto;
|
flex: auto;
|
||||||
}
|
}
|
||||||
`
|
`
|
||||||
|
|
||||||
|
export default (() => Header) satisfies QuartzComponentConstructor
|
||||||
|
@ -1,9 +1,11 @@
|
|||||||
import { resolveToRoot } from "../path"
|
import { resolveToRoot } from "../path"
|
||||||
import { QuartzComponentProps } from "./types"
|
import { QuartzComponentConstructor, QuartzComponentProps } from "./types"
|
||||||
|
|
||||||
export default function({ cfg, fileData }: QuartzComponentProps) {
|
function PageTitle({ cfg, fileData }: QuartzComponentProps) {
|
||||||
const title = cfg.siteTitle
|
const title = cfg.siteTitle
|
||||||
const slug = fileData.slug!
|
const slug = fileData.slug!
|
||||||
const baseDir = resolveToRoot(slug)
|
const baseDir = resolveToRoot(slug)
|
||||||
return <h1><a href={baseDir}>{title}</a></h1>
|
return <h1><a href={baseDir}>{title}</a></h1>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export default (() => PageTitle) satisfies QuartzComponentConstructor
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import { QuartzComponentProps } from "./types"
|
import { QuartzComponentConstructor, QuartzComponentProps } from "./types"
|
||||||
import readingTime from "reading-time"
|
import readingTime from "reading-time"
|
||||||
|
|
||||||
export default function ReadingTime({ fileData }: QuartzComponentProps) {
|
function ReadingTime({ fileData }: QuartzComponentProps) {
|
||||||
const text = fileData.text
|
const text = fileData.text
|
||||||
const isHomePage = fileData.slug === "index"
|
const isHomePage = fileData.slug === "index"
|
||||||
if (text && !isHomePage) {
|
if (text && !isHomePage) {
|
||||||
@ -18,3 +18,5 @@ ReadingTime.css = `
|
|||||||
opacity: 0.5;
|
opacity: 0.5;
|
||||||
}
|
}
|
||||||
`
|
`
|
||||||
|
|
||||||
|
export default (() => ReadingTime) satisfies QuartzComponentConstructor
|
||||||
|
@ -1,3 +1,7 @@
|
|||||||
export default function() {
|
import { QuartzComponentConstructor } from "./types"
|
||||||
|
|
||||||
|
function Spacer() {
|
||||||
return <div class="spacer"></div>
|
return <div class="spacer"></div>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export default (() => Spacer) satisfies QuartzComponentConstructor
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import { QuartzComponentProps } from "./types"
|
import { QuartzComponentConstructor, QuartzComponentProps } from "./types"
|
||||||
import style from "./styles/toc.scss"
|
import style from "./styles/toc.scss"
|
||||||
|
|
||||||
export default function TableOfContents({ fileData }: QuartzComponentProps) {
|
function TableOfContents({ fileData }: QuartzComponentProps) {
|
||||||
if (!fileData.toc) {
|
if (!fileData.toc) {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
@ -17,3 +17,5 @@ export default function TableOfContents({ fileData }: QuartzComponentProps) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TableOfContents.css = style
|
TableOfContents.css = style
|
||||||
|
|
||||||
|
export default (() => TableOfContents) satisfies QuartzComponentConstructor
|
||||||
|
@ -18,4 +18,4 @@ export type QuartzComponent = ComponentType<QuartzComponentProps> & {
|
|||||||
afterDOMLoaded?: string,
|
afterDOMLoaded?: string,
|
||||||
}
|
}
|
||||||
|
|
||||||
export type QuartzComponentConstructor<Options extends object> = (opts: Options) => QuartzComponent
|
export type QuartzComponentConstructor<Options extends object | undefined = undefined> = (opts: Options) => QuartzComponent
|
||||||
|
@ -5,9 +5,9 @@ import { render } from "preact-render-to-string"
|
|||||||
import { GlobalConfiguration } from "../../cfg"
|
import { GlobalConfiguration } from "../../cfg"
|
||||||
import { QuartzComponent } from "../../components/types"
|
import { QuartzComponent } from "../../components/types"
|
||||||
import { resolveToRoot } from "../../path"
|
import { resolveToRoot } from "../../path"
|
||||||
import Header from "../../components/Header"
|
import HeaderConstructor from "../../components/Header"
|
||||||
import { QuartzComponentProps } from "../../components/types"
|
import { QuartzComponentProps } from "../../components/types"
|
||||||
import Body from "../../components/Body"
|
import BodyConstructor from "../../components/Body"
|
||||||
|
|
||||||
interface Options {
|
interface Options {
|
||||||
head: QuartzComponent
|
head: QuartzComponent
|
||||||
@ -20,6 +20,10 @@ export const ContentPage: QuartzEmitterPlugin<Options> = (opts) => {
|
|||||||
throw new Error("ContentPage must be initialized with options specifiying the components to use")
|
throw new Error("ContentPage must be initialized with options specifiying the components to use")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const { head: Head, header, body } = opts
|
||||||
|
const Header = HeaderConstructor()
|
||||||
|
const Body = BodyConstructor()
|
||||||
|
|
||||||
return {
|
return {
|
||||||
name: "ContentPage",
|
name: "ContentPage",
|
||||||
getQuartzComponents() {
|
getQuartzComponents() {
|
||||||
@ -28,7 +32,6 @@ export const ContentPage: QuartzEmitterPlugin<Options> = (opts) => {
|
|||||||
async emit(cfg: GlobalConfiguration, content: ProcessedContent[], resources: StaticResources, emit: EmitCallback): Promise<string[]> {
|
async emit(cfg: GlobalConfiguration, content: ProcessedContent[], resources: StaticResources, emit: EmitCallback): Promise<string[]> {
|
||||||
const fps: string[] = []
|
const fps: string[] = []
|
||||||
|
|
||||||
const { head: Head, header, body } = opts
|
|
||||||
for (const [tree, file] of content) {
|
for (const [tree, file] of content) {
|
||||||
const baseDir = resolveToRoot(file.data.slug!)
|
const baseDir = resolveToRoot(file.data.slug!)
|
||||||
const pageResources: StaticResources = {
|
const pageResources: StaticResources = {
|
||||||
|
Loading…
Reference in New Issue
Block a user