This commit is contained in:
Jacky Zhao 2023-06-09 23:06:02 -07:00
parent 3a29f4c86e
commit b8c011410d
21 changed files with 233 additions and 66 deletions

View file

@ -0,0 +1,11 @@
import { QuartzComponentProps } from "./types"
export default function ArticleTitle({ fileData }: QuartzComponentProps) {
const title = fileData.frontmatter?.title
const displayTitle = fileData.slug === "index" ? undefined : title
if (displayTitle) {
return <h1>{displayTitle}</h1>
} else {
return null
}
}

View file

@ -2,13 +2,8 @@ import clipboardScript from './scripts/clipboard.inline'
import clipboardStyle from './styles/clipboard.scss'
import { QuartzComponentProps } from "./types"
export default function Body({ fileData, children }: QuartzComponentProps) {
const title = fileData.frontmatter?.title
const displayTitle = fileData.slug === "index" ? undefined : title
export default function Body({ children }: QuartzComponentProps) {
return <article>
<div class="top-section">
{displayTitle && <h1>{displayTitle}</h1>}
</div>
{children}
</article>
}

View file

@ -0,0 +1,9 @@
import { QuartzComponentProps } from "./types"
import { Fragment, jsx, jsxs } from 'preact/jsx-runtime'
import { toJsxRuntime } from "hast-util-to-jsx-runtime"
export default function Content({ tree }: QuartzComponentProps) {
// @ts-ignore (preact makes it angry)
const content = toJsxRuntime(tree, { Fragment, jsx, jsxs, elementAttributeNameCase: 'html' })
return content
}

View file

@ -1,4 +1,3 @@
import style from './styles/header.scss'
import { QuartzComponentProps } from "./types"
export default function Header({ children }: QuartzComponentProps) {
@ -7,4 +6,18 @@ export default function Header({ children }: QuartzComponentProps) {
</header>
}
Header.css = style
Header.css = `
header {
display: flex;
flex-direction: row;
align-items: center;
margin: 1em 0 2em 0;
& > h1 {
}
}
header > h1 {
margin: 0;
flex: auto;
}
`

View file

@ -0,0 +1,20 @@
import { QuartzComponentProps } from "./types"
import readingTime from "reading-time"
export default function ReadingTime({ fileData }: QuartzComponentProps) {
const text = fileData.text
const isHomePage = fileData.slug === "index"
if (text && !isHomePage) {
const { text: timeTaken, words } = readingTime(text)
return <p class="reading-time">{words} words, {timeTaken}</p>
} else {
return null
}
}
ReadingTime.css = `
.reading-time {
margin-top: 0;
opacity: 0.5;
}
`

View file

@ -0,0 +1,24 @@
import { QuartzComponentProps } from "./types"
import style from "./styles/toc.scss"
export default function TableOfContents({ fileData, position }: QuartzComponentProps) {
if (!fileData.toc) {
return null
}
if (position === 'body') {
// TODO: animate this
return <details className="toc" open>
<summary><h3>Table of Contents</h3></summary>
<ul>
{fileData.toc.map(tocEntry => <li key={tocEntry.slug} className={`depth-${tocEntry.depth}`}>
<a href={`#${tocEntry.slug}`}>{tocEntry.text}</a>
</li>)}
</ul>
</details>
} else if (position === 'sidebar') {
// TODO
}
}
TableOfContents.css = style

View file

@ -0,0 +1,19 @@
import ArticleTitle from "./ArticleTitle"
import Content from "./Content"
import Darkmode from "./Darkmode"
import Head from "./Head"
import PageTitle from "./PageTitle"
import ReadingTime from "./ReadingTime"
import Spacer from "./Spacer"
import TableOfContents from "./TableOfContents"
export {
ArticleTitle,
Content,
Darkmode,
Head,
PageTitle,
ReadingTime,
Spacer,
TableOfContents
}

View file

@ -1,10 +0,0 @@
header {
display: flex;
flex-direction: row;
align-items: center;
margin: 1em 0 2em 0;
& > h1 {
margin: 0;
flex: auto;
}
}

View file

@ -0,0 +1,27 @@
details.toc {
& summary {
cursor: pointer;
&::marker {
color: var(--dark);
}
& > * {
padding-left: 0.25rem;
display: inline-block;
margin: 0;
}
}
& ul {
list-style: none;
margin: 0.5rem 1.25rem;
padding: 0;
}
@for $i from 1 through 6 {
& .depth-#{$i} {
padding-left: calc(1rem * #{$i});
}
}
}

View file

@ -2,12 +2,15 @@ import { ComponentType, JSX } from "preact"
import { StaticResources } from "../resources"
import { QuartzPluginData } from "../plugins/vfile"
import { GlobalConfiguration } from "../cfg"
import { Node } from "hast"
export type QuartzComponentProps = {
externalResources: StaticResources
fileData: QuartzPluginData
cfg: GlobalConfiguration
children: QuartzComponent[] | JSX.Element[]
tree: Node<QuartzPluginData>
position?: 'sidebar' | 'header' | 'body'
}
export type QuartzComponent = ComponentType<QuartzComponentProps> & {