Skip to content

Commit 715f9b6

Browse files
Merge pull request #8 from PrathameshDhande22/blogs-page. Fixes #3
Feature: New Blogs Page where it shows all the Patterns Blogs
2 parents 26c0d14 + 952818c commit 715f9b6

11 files changed

+204
-13
lines changed

quartz.config.ts

+1
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ const config: QuartzConfig = {
8888
Plugin.Assets(),
8989
Plugin.Static(),
9090
Plugin.NotFoundPage(),
91+
Plugin.ExplorerWithTocPage(),
9192
],
9293
},
9394
}

quartz.layout.ts

+3
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,9 @@ export const defaultContentPageLayout: PageLayout = {
5252
Component.Explorer({
5353
title: "Patterns",
5454
folderDefaultState: "open",
55+
sortFn: (a, b) => {
56+
return b.file?.dates?.created.valueOf()! - a.file?.dates?.created.valueOf()!
57+
}
5558
})
5659
)
5760
],

quartz/components/Drawer.tsx

+6-2
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,9 @@ export default ((opts?: Options) => {
1616
const links = opts?.links ?? []
1717
const fileTree = new FileNode("")
1818
allFiles.forEach((file) => fileTree.add(file))
19-
19+
allFiles = allFiles.sort((a, b) => {
20+
return b.dates?.created.valueOf()! - a.dates?.created.valueOf()!
21+
})
2022
return (
2123
<div class="drawer">
2224
<div class="drawer-wrapper">
@@ -57,7 +59,9 @@ export default ((opts?: Options) => {
5759
{allFiles.map((value) => {
5860
return (
5961
<li key={value.slug}>
60-
<a href={resolveRelative(value.slug!, value.slug!)} data-for={value.slug}>{value.frontmatter?.title}</a>
62+
<a href={resolveRelative(value.slug!, value.slug!)} data-for={value.slug}>
63+
{value.frontmatter?.title}
64+
</a>
6165
</li>
6266
)
6367
})}

quartz/components/pages/Blogs.tsx

+64-8
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,71 @@
1+
import { classNames } from "../../util/lang"
12
import { QuartzComponent, QuartzComponentConstructor, QuartzComponentProps } from "../types"
2-
import style from "./styles/navigationheader.scss"
3+
import styles from "../styles/blogs.scss"
4+
// @ts-ignore
5+
import script from "../scripts/blogpatterns.inline"
36

4-
interface Options {
5-
links: Record<string, string>
6-
components: QuartzComponent[]
7-
}
8-
9-
export default ((opts?: Options) => {
7+
export default (() => {
108
const Blogs: QuartzComponent = (props: QuartzComponentProps) => {
11-
return <div>Blogs Page</div>
9+
/**
10+
* Sorts all files in descending order based on their creation date.
11+
*
12+
* @param props - The component props containing the allFiles array.
13+
* @returns An array of sorted files with the most recently created files first.
14+
*/
15+
const allFiles = props.allFiles.sort((a, b) => {
16+
return b.dates?.created.valueOf()! - a.dates?.created.valueOf()!
17+
})
18+
return (
19+
<div class="toc-elements">
20+
{allFiles.map((data, index) => {
21+
return (
22+
<div class={classNames(props.displayClass, "toc")}>
23+
<button
24+
type="button"
25+
id="toc"
26+
class={classNames(
27+
props.displayClass,
28+
!data.collapseToc ? "collapsed" : "",
29+
"toc-button",
30+
)}
31+
aria-controls="toc-content"
32+
aria-expanded={!data.collapseToc}
33+
>
34+
<h3>{data.frontmatter?.title}</h3>
35+
<svg
36+
xmlns="http://www.w3.org/2000/svg"
37+
width="24"
38+
height="24"
39+
viewBox="0 0 24 24"
40+
fill="none"
41+
stroke="currentColor"
42+
stroke-width="2"
43+
stroke-linecap="round"
44+
stroke-linejoin="round"
45+
class="fold"
46+
>
47+
<polyline points="6 9 12 15 18 9"></polyline>
48+
</svg>
49+
</button>
50+
<div id="toc-content" class={!props.fileData.collapseToc ? "collapsed" : ""}>
51+
<ul class="overflow">
52+
{data.toc?.map((tocEntry) => (
53+
<li key={tocEntry.slug} class={`depth-${tocEntry.depth}`}>
54+
<a href={`${data.slug}#${tocEntry.slug}`} data-for={tocEntry.slug}>
55+
{tocEntry.text}
56+
</a>
57+
</li>
58+
))}
59+
</ul>
60+
</div>
61+
</div>
62+
)
63+
})}
64+
</div>
65+
)
1266
}
1367

68+
Blogs.css = styles
69+
Blogs.afterDOMLoaded = script
1470
return Blogs
1571
}) satisfies QuartzComponentConstructor
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
const tocbutton = document.querySelectorAll(".toc-button")
2+
3+
function closeAllToc(exclude: Element) {
4+
tocbutton.forEach((value) => {
5+
if (value !== exclude && !value.classList.contains("collapsed")) {
6+
toggleToc(value)
7+
}
8+
})
9+
}
10+
11+
function toggleToc(value: Element) {
12+
console.log("triggerd")
13+
value.classList.toggle("collapsed")
14+
value.nextElementSibling?.classList.toggle("collapsed")
15+
}
16+
17+
tocbutton.forEach((value) => {
18+
value.addEventListener("click", () => {
19+
closeAllToc(value)
20+
21+
toggleToc(value)
22+
})
23+
})

quartz/components/scripts/drawer.inline.ts

-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ import { assignActiveClassToDrawerButton } from "./util"
33
const drawerele = document.querySelector(".drawer")
44
drawerele?.addEventListener("click", () => {
55
drawerele.classList.remove("active")
6-
76
const isdrawerActive: boolean = drawerele.classList.contains("active")
87
assignActiveClassToDrawerButton(isdrawerActive)
98
})

quartz/components/scripts/navigationlinks.inline.ts

-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ let drawer = document.getElementsByClassName("drawer")[0]
44

55
document.getElementsByClassName("menu-btn")[0].addEventListener("click", () => {
66
drawer.classList.add("active")
7-
87
const isdrawerActive: boolean = drawer.classList.contains("active")
98
assignActiveClassToDrawerButton(isdrawerActive)
109
})

quartz/components/styles/blogs.scss

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
.toc-elements {
2+
display: flex;
3+
flex-direction: column;
4+
gap: 10px;
5+
}

quartz/components/styles/drawer.scss

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
top: 0px;
66
right: 0;
77
width: 100vw;
8-
transform: translateX(-100%);
8+
transform: translateX(-104%);
99
transition: transform 0.3s ease;
1010
height: 100vh;
1111
background-color: rgba(0, 0, 0, 0.5);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
import { QuartzEmitterPlugin } from "../types"
2+
import { QuartzComponentProps } from "../../components/types"
3+
import HeaderConstructor from "../../components/Header"
4+
import BodyConstructor from "../../components/Body"
5+
import { pageResources, renderPage } from "../../components/renderPage"
6+
import { QuartzPluginData, defaultProcessedContent } from "../vfile"
7+
import { FullPageLayout } from "../../cfg"
8+
import {
9+
FilePath,
10+
FullSlug,
11+
pathToRoot,
12+
} from "../../util/path"
13+
import {
14+
defaultContentPageLayout,
15+
sharedPageComponents,
16+
} from "../../../quartz.layout"
17+
import { write } from "./helpers"
18+
import DepGraph from "../../depgraph"
19+
import Blogs from "../../components/pages/Blogs"
20+
21+
interface ExplorerWithTocPageOptions extends FullPageLayout {
22+
sort?: (f1: QuartzPluginData, f2: QuartzPluginData) => number
23+
}
24+
25+
export const ExplorerWithTocPage: QuartzEmitterPlugin<Partial<ExplorerWithTocPageOptions>> = (
26+
userOpts,
27+
) => {
28+
const opts: FullPageLayout = {
29+
...sharedPageComponents,
30+
...defaultContentPageLayout,
31+
pageBody: Blogs(),
32+
...userOpts,
33+
}
34+
35+
const {
36+
head: Head,
37+
header,
38+
navbar,
39+
beforeBody,
40+
pageBody,
41+
afterBody,
42+
left,
43+
right,
44+
footer: Footer,
45+
} = opts
46+
const Header = HeaderConstructor()
47+
const Body = BodyConstructor()
48+
49+
return {
50+
name: "DesignPatterns",
51+
getQuartzComponents() {
52+
return [
53+
Head,
54+
Header,
55+
...navbar,
56+
Body,
57+
...header,
58+
...beforeBody,
59+
pageBody,
60+
...afterBody,
61+
...left,
62+
...right,
63+
Footer,
64+
]
65+
},
66+
async getDependencyGraph(_ctx, _content, _resources) {
67+
return new DepGraph<FilePath>()
68+
},
69+
async emit(ctx, _content, resources): Promise<FilePath[]> {
70+
const cfg = ctx.cfg.configuration
71+
const allFiles = _content.map((c) => c[1].data)
72+
const slug = "blogs" as FullSlug
73+
const title = "Pattern Blogs"
74+
const [tree, vfile] = defaultProcessedContent({
75+
slug,
76+
text: title,
77+
frontmatter: { title: title, tags: [] },
78+
})
79+
const externalResources = pageResources(pathToRoot(slug), vfile.data, resources)
80+
const componentData: QuartzComponentProps = {
81+
ctx,
82+
fileData: vfile.data,
83+
externalResources,
84+
cfg,
85+
children: [],
86+
tree,
87+
allFiles: allFiles,
88+
}
89+
90+
return [
91+
await write({
92+
ctx,
93+
content: renderPage(cfg, slug, componentData, opts, externalResources),
94+
slug,
95+
ext: ".html",
96+
}),
97+
]
98+
},
99+
}
100+
}

quartz/plugins/emitters/index.ts

+1
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,4 @@ export { Static } from "./static"
88
export { ComponentResources } from "./componentResources"
99
export { NotFoundPage } from "./404"
1010
export { CNAME } from "./cname"
11+
export { ExplorerWithTocPage } from "./explorerwithtocPage"

0 commit comments

Comments
 (0)