From cb89cce183215f6a8edcb6d166875e2982586002 Mon Sep 17 00:00:00 2001 From: Jacky Zhao <j.zhao2k19@gmail.com> Date: Sat, 17 Jun 2023 14:36:06 -0700 Subject: [PATCH] basic left,right layout --- quartz.config.ts | 11 +++++---- quartz/components/TagList.tsx | 2 +- quartz/components/scripts/callout.inline.ts | 26 +++++++++++---------- quartz/components/scripts/toc.inline.ts | 13 +++++++---- quartz/components/styles/darkmode.scss | 4 ---- quartz/plugins/emitters/contentPage.tsx | 20 ++++++++++++---- quartz/plugins/transformers/ofm.ts | 2 -- quartz/styles/base.scss | 23 ++++++++++++++++++ quartz/styles/callouts.scss | 5 +++- 9 files changed, 73 insertions(+), 33 deletions(-) diff --git a/quartz.config.ts b/quartz.config.ts index 0c77c90..e18f8ba 100644 --- a/quartz.config.ts +++ b/quartz.config.ts @@ -59,15 +59,16 @@ const config: QuartzConfig = { Plugin.ContentPage({ head: Component.Head(), header: [Component.PageTitle(), Component.Spacer(), Component.Darkmode()], - body: [ + beforeBody: [ Component.ArticleTitle(), Component.ReadingTime(), Component.TagList(), - Component.TableOfContents(), - Component.Content() ], - left: [], - right: [], + left: [ + Component.TableOfContents(), + ], + right: [ + ], footer: [] }), Plugin.ContentIndex(), // you can exclude this if you don't plan on using popovers, graph, or backlinks, diff --git a/quartz/components/TagList.tsx b/quartz/components/TagList.tsx index a462e95..65286a5 100644 --- a/quartz/components/TagList.tsx +++ b/quartz/components/TagList.tsx @@ -6,7 +6,7 @@ function TagList({ fileData }: QuartzComponentProps) { const tags = fileData.frontmatter?.tags const slug = fileData.slug! const baseDir = resolveToRoot(slug) - if (tags) { + if (tags && tags.length > 0) { return <ul class="tags">{tags.map(tag => { const display = `#${tag}` const linkDest = baseDir + `/tags/${slugAnchor(tag)}` diff --git a/quartz/components/scripts/callout.inline.ts b/quartz/components/scripts/callout.inline.ts index 5f35873..081a5a2 100644 --- a/quartz/components/scripts/callout.inline.ts +++ b/quartz/components/scripts/callout.inline.ts @@ -6,19 +6,21 @@ function toggleCallout(this: HTMLElement) { outerBlock.style.maxHeight = height + `px` } -function setupCallout(div: HTMLElement) { - const collapsed = div.classList.contains(`is-collapsed`) - const title = div.firstElementChild! - const height = collapsed ? title.scrollHeight : div.scrollHeight - div.style.maxHeight = height + `px` -} - -document.addEventListener(`nav`, () => { +function setupCallout() { const collapsible = document.getElementsByClassName(`callout is-collapsible`) as HTMLCollectionOf<HTMLElement> for (const div of collapsible) { const title = div.firstElementChild - setupCallout(div) - title?.removeEventListener(`click`, toggleCallout) - title?.addEventListener(`click`, toggleCallout) + + if (title) { + title.removeEventListener(`click`, toggleCallout) + title.addEventListener(`click`, toggleCallout) + + const collapsed = div.classList.contains(`is-collapsed`) + const height = collapsed ? title.scrollHeight : div.scrollHeight + div.style.maxHeight = height + `px` + } } -}) +} + +document.addEventListener(`nav`, setupCallout) +window.addEventListener(`resize`, setupCallout) diff --git a/quartz/components/scripts/toc.inline.ts b/quartz/components/scripts/toc.inline.ts index 405a21f..105889d 100644 --- a/quartz/components/scripts/toc.inline.ts +++ b/quartz/components/scripts/toc.inline.ts @@ -14,19 +14,24 @@ const observer = new IntersectionObserver(entries => { } }) -function toggleCollapsible(this: HTMLElement) { +function toggleToc(this: HTMLElement) { this.classList.toggle("collapsed") const content = this.nextElementSibling as HTMLElement content.classList.toggle("collapsed") content.style.maxHeight = content.style.maxHeight === "0px" ? content.scrollHeight + "px" : "0px" } -document.addEventListener("nav", () => { +function setupToc() { const toc = document.getElementById("toc")! const content = toc.nextElementSibling as HTMLElement content.style.maxHeight = content.scrollHeight + "px" - toc.removeEventListener("click", toggleCollapsible) - toc.addEventListener("click", toggleCollapsible) + toc.removeEventListener("click", toggleToc) + toc.addEventListener("click", toggleToc) +} + +window.addEventListener("resize", setupToc) +document.addEventListener("nav", () => { + setupToc() // update toc entry highlighting observer.disconnect() diff --git a/quartz/components/styles/darkmode.scss b/quartz/components/styles/darkmode.scss index 561a83c..46291d8 100644 --- a/quartz/components/styles/darkmode.scss +++ b/quartz/components/styles/darkmode.scss @@ -4,10 +4,6 @@ min-width: 30px; position: relative; - @media all and (max-width: 450px) { - padding: 1rem; - } - & > .toggle { display: none; box-sizing: border-box; diff --git a/quartz/plugins/emitters/contentPage.tsx b/quartz/plugins/emitters/contentPage.tsx index 7afab9d..ea626f5 100644 --- a/quartz/plugins/emitters/contentPage.tsx +++ b/quartz/plugins/emitters/contentPage.tsx @@ -6,11 +6,12 @@ import { resolveToRoot } from "../../path" import HeaderConstructor from "../../components/Header" import { QuartzComponentProps } from "../../components/types" import BodyConstructor from "../../components/Body" +import ContentConstructor from "../../components/Content" interface Options { head: QuartzComponent header: QuartzComponent[], - body: QuartzComponent[], + beforeBody: QuartzComponent[], left: QuartzComponent[], right: QuartzComponent[], footer: QuartzComponent[], @@ -21,14 +22,15 @@ export const ContentPage: QuartzEmitterPlugin<Options> = (opts) => { throw new Error("ContentPage must be initialized with options specifiying the components to use") } - const { head: Head, header, body } = opts + const { head: Head, header, beforeBody, left, right, footer } = opts const Header = HeaderConstructor() const Body = BodyConstructor() + const Content = ContentConstructor() return { name: "ContentPage", getQuartzComponents() { - return [opts.head, Header, Body, ...opts.header, ...opts.body, ...opts.left, ...opts.right, ...opts.footer] + return [opts.head, Header, Body, ...opts.header, ...opts.beforeBody, ...opts.left, ...opts.right, ...opts.footer] }, async emit(_contentDir, cfg, content, resources, emit): Promise<string[]> { const fps: string[] = [] @@ -59,9 +61,19 @@ export const ContentPage: QuartzEmitterPlugin<Options> = (opts) => { <Header {...componentData} > {header.map(HeaderComponent => <HeaderComponent {...componentData} />)} </Header> + {beforeBody.map(BodyComponent => <BodyComponent {...componentData} />)} <Body {...componentData}> - {body.map(BodyComponent => <BodyComponent {...componentData} />)} + <div class="left"> + {left.map(BodyComponent => <BodyComponent {...componentData} />)} + </div> + <div class="center"> + <Content {...componentData} /> + </div> + <div class="right"> + {right.map(BodyComponent => <BodyComponent {...componentData} />)} + </div> </Body> + </div> </body> {pageResources.js.filter(resource => resource.loadTime === "afterDOMReady").map(res => JSResourceToScriptElement(res))} diff --git a/quartz/plugins/transformers/ofm.ts b/quartz/plugins/transformers/ofm.ts index 4ade476..3742d4b 100644 --- a/quartz/plugins/transformers/ofm.ts +++ b/quartz/plugins/transformers/ofm.ts @@ -300,8 +300,6 @@ export const ObsidianFlavoredMarkdown: QuartzTransformerPlugin<Partial<Options> }) } - console.log(js) - return { js } } } diff --git a/quartz/styles/base.scss b/quartz/styles/base.scss index d7a1891..9fc76f9 100644 --- a/quartz/styles/base.scss +++ b/quartz/styles/base.scss @@ -51,8 +51,31 @@ a { padding: 4rem 30vw; margin: 0 auto; max-width: 1000px; + position: relative; + + & .left, & .right { + position: fixed; + padding: 0 4rem 0 6rem; + max-width: 30vw; + box-sizing: border-box; + top: 10rem; + } + + & .left { + left: 0; + } + + & .right { + right: 0; + } + @media all and (max-width: 1200px) { padding: 25px 5vw; + & .left, & .right { + padding: 0; + max-width: none; + position: initial; + } } & p { diff --git a/quartz/styles/callouts.scss b/quartz/styles/callouts.scss index 84d70b4..d33d78b 100644 --- a/quartz/styles/callouts.scss +++ b/quartz/styles/callouts.scss @@ -8,6 +8,10 @@ overflow-y: hidden; transition: max-height 0.3s ease; + & > *:nth-child(2) { + margin-top: 0; + } + &[data-callout="note"] { --color: #448aff; --border: #448aff22; @@ -74,7 +78,6 @@ align-items: center; gap: 5px; padding: 1rem 0; - margin-bottom: -1rem; color: var(--color); & .fold {