Compare commits

..

No commits in common. "580c1bd608771efc15cf9cdf1784aba74ed83240" and "ca08ec1ae7c0003a186fb5a38b56208d4baf30bd" have entirely different histories.

8 changed files with 27 additions and 127 deletions

View File

@ -108,25 +108,3 @@ Some plugins are included by default in the [`quartz.config.ts`](https://github.
You can see a list of all plugins and their configuration options [[tags/plugin|here]]. You can see a list of all plugins and their configuration options [[tags/plugin|here]].
If you'd like to make your own plugins, see the [[making plugins|making custom plugins]] guide. If you'd like to make your own plugins, see the [[making plugins|making custom plugins]] guide.
## Fonts
Fonts can be specified as a `string` or a `FontSpecification`:
```ts
// string
typography: {
header: "Schibsted Grotesk",
...
}
// FontSpecification
typography: {
header: {
name: "Schibsted Grotesk",
weights: [400, 700],
includeItalic: true,
},
...
}
```

View File

@ -49,15 +49,8 @@ export const defaultListPageLayout: PageLayout = {
left: [ left: [
Component.PageTitle(), Component.PageTitle(),
Component.MobileOnly(Component.Spacer()), Component.MobileOnly(Component.Spacer()),
Component.Flex({ Component.Search(),
components: [ Component.Darkmode(),
{
Component: Component.Search(),
grow: true,
},
{ Component: Component.Darkmode() },
],
}),
Component.Explorer(), Component.Explorer(),
], ],
right: [], right: [],

View File

@ -259,17 +259,15 @@ document.addEventListener("nav", async (e: CustomEventMap["nav"]) => {
await setupExplorer(currentSlug) await setupExplorer(currentSlug)
// if mobile hamburger is visible, collapse by default // if mobile hamburger is visible, collapse by default
for (const explorer of document.getElementsByClassName("explorer")) { for (const explorer of document.getElementsByClassName("mobile-explorer")) {
const mobileExplorer = explorer.querySelector(".mobile-explorer") if (explorer.checkVisibility()) {
if (!mobileExplorer) return
if (mobileExplorer.checkVisibility()) {
explorer.classList.add("collapsed") explorer.classList.add("collapsed")
explorer.setAttribute("aria-expanded", "false") explorer.setAttribute("aria-expanded", "false")
} }
mobileExplorer.classList.remove("hide-until-loaded")
} }
const hiddenUntilDoneLoading = document.querySelector(".mobile-explorer")
hiddenUntilDoneLoading?.classList.remove("hide-until-loaded")
}) })
function setFolderState(folderElement: HTMLElement, collapsed: boolean) { function setFolderState(folderElement: HTMLElement, collapsed: boolean) {

View File

@ -212,8 +212,8 @@ li:has(> .folder-outer:not(.open)) > .folder-container > svg {
flex: 0 0 34px; flex: 0 0 34px;
& > .explorer-content { & > .explorer-content {
transform: translateX(-100vw); transform: translateX(0);
visibility: hidden; visibility: visible;
} }
} }
@ -221,8 +221,8 @@ li:has(> .folder-outer:not(.open)) > .folder-container > svg {
flex: 0 0 34px; flex: 0 0 34px;
& > .explorer-content { & > .explorer-content {
transform: translateX(0); transform: translateX(-100vw);
visibility: visible; visibility: hidden;
} }
} }
@ -236,7 +236,7 @@ li:has(> .folder-outer:not(.open)) > .folder-container > svg {
background-color: var(--light); background-color: var(--light);
max-width: 100vw; max-width: 100vw;
width: 100%; width: 100%;
transform: translateX(-100vw); transform: translateX(0);
transition: transition:
transform 200ms ease, transform 200ms ease,
visibility 200ms ease; visibility 200ms ease;

View File

@ -12,7 +12,6 @@ import DepGraph from "../../depgraph"
export type ContentIndexMap = Map<FullSlug, ContentDetails> export type ContentIndexMap = Map<FullSlug, ContentDetails>
export type ContentDetails = { export type ContentDetails = {
slug: FullSlug slug: FullSlug
filePath: FilePath
title: string title: string
links: SimpleSlug[] links: SimpleSlug[]
tags: string[] tags: string[]
@ -127,7 +126,6 @@ export const ContentIndex: QuartzEmitterPlugin<Partial<Options>> = (opts) => {
if (opts?.includeEmptyFiles || (file.data.text && file.data.text !== "")) { if (opts?.includeEmptyFiles || (file.data.text && file.data.text !== "")) {
linkIndex.set(slug, { linkIndex.set(slug, {
slug, slug,
filePath: file.data.filePath!,
title: file.data.frontmatter?.title!, title: file.data.frontmatter?.title!,
links: file.data.links ?? [], links: file.data.links ?? [],
tags: file.data.frontmatter?.tags ?? [], tags: file.data.frontmatter?.tags ?? [],

View File

@ -5,7 +5,6 @@ import { FileTrieNode } from "./fileTrie"
interface TestData { interface TestData {
title: string title: string
slug: string slug: string
filePath: string
} }
describe("FileTrie", () => { describe("FileTrie", () => {
@ -27,24 +26,11 @@ describe("FileTrie", () => {
const data = { const data = {
title: "Test Title", title: "Test Title",
slug: "test", slug: "test",
filePath: "test.md",
} }
trie.add(data) trie.add(data)
assert.strictEqual(trie.children[0].displayName, "Test Title") assert.strictEqual(trie.children[0].displayName, "Test Title")
}) })
test("should be able to set displayName", () => {
const data = {
title: "Test Title",
slug: "test",
filePath: "test.md",
}
trie.add(data)
trie.children[0].displayName = "Modified"
assert.strictEqual(trie.children[0].displayName, "Modified")
})
}) })
describe("add", () => { describe("add", () => {
@ -52,7 +38,6 @@ describe("FileTrie", () => {
const data = { const data = {
title: "Test", title: "Test",
slug: "test", slug: "test",
filePath: "test.md",
} }
trie.add(data) trie.add(data)
@ -65,7 +50,6 @@ describe("FileTrie", () => {
const data = { const data = {
title: "Index", title: "Index",
slug: "index", slug: "index",
filePath: "index.md",
} }
trie.add(data) trie.add(data)
@ -77,13 +61,11 @@ describe("FileTrie", () => {
const data1 = { const data1 = {
title: "Nested", title: "Nested",
slug: "folder/test", slug: "folder/test",
filePath: "folder/test.md",
} }
const data2 = { const data2 = {
title: "Really nested index", title: "Really nested index",
slug: "a/b/c/index", slug: "a/b/c/index",
filePath: "a/b/c/index.md",
} }
trie.add(data1) trie.add(data1)
@ -110,8 +92,8 @@ describe("FileTrie", () => {
describe("filter", () => { describe("filter", () => {
test("should filter nodes based on condition", () => { test("should filter nodes based on condition", () => {
const data1 = { title: "Test1", slug: "test1", filePath: "test1.md" } const data1 = { title: "Test1", slug: "test1" }
const data2 = { title: "Test2", slug: "test2", filePath: "test2.md" } const data2 = { title: "Test2", slug: "test2" }
trie.add(data1) trie.add(data1)
trie.add(data2) trie.add(data2)
@ -124,8 +106,8 @@ describe("FileTrie", () => {
describe("map", () => { describe("map", () => {
test("should apply function to all nodes", () => { test("should apply function to all nodes", () => {
const data1 = { title: "Test1", slug: "test1", filePath: "test1.md" } const data1 = { title: "Test1", slug: "test1" }
const data2 = { title: "Test2", slug: "test2", filePath: "test2.md" } const data2 = { title: "Test2", slug: "test2" }
trie.add(data1) trie.add(data1)
trie.add(data2) trie.add(data2)
@ -139,41 +121,12 @@ describe("FileTrie", () => {
assert.strictEqual(trie.children[0].displayName, "Modified") assert.strictEqual(trie.children[0].displayName, "Modified")
assert.strictEqual(trie.children[1].displayName, "Modified") assert.strictEqual(trie.children[1].displayName, "Modified")
}) })
test("map over folders should work", () => {
const data1 = { title: "Test1", slug: "test1", filePath: "test1.md" }
const data2 = {
title: "Test2",
slug: "a/b-with-space/test2",
filePath: "a/b with space/test2.md",
}
trie.add(data1)
trie.add(data2)
trie.map((node) => {
if (node.isFolder) {
node.displayName = `Folder: ${node.displayName}`
} else {
node.displayName = `File: ${node.displayName}`
}
})
assert.strictEqual(trie.children[0].displayName, "File: Test1")
assert.strictEqual(trie.children[1].displayName, "Folder: a")
assert.strictEqual(trie.children[1].children[0].displayName, "Folder: b with space")
assert.strictEqual(trie.children[1].children[0].children[0].displayName, "File: Test2")
})
}) })
describe("entries", () => { describe("entries", () => {
test("should return all entries", () => { test("should return all entries", () => {
const data1 = { title: "Test1", slug: "test1", filePath: "test1.md" } const data1 = { title: "Test1", slug: "test1" }
const data2 = { const data2 = { title: "Test2", slug: "a/b/test2" }
title: "Test2",
slug: "a/b-with-space/test2",
filePath: "a/b with space/test2.md",
}
trie.add(data1) trie.add(data1)
trie.add(data2) trie.add(data2)
@ -185,8 +138,8 @@ describe("FileTrie", () => {
["index", trie.data], ["index", trie.data],
["test1", data1], ["test1", data1],
["a/index", null], ["a/index", null],
["a/b-with-space/index", null], ["a/b/index", null],
["a/b-with-space/test2", data2], ["a/b/test2", data2],
], ],
) )
}) })
@ -197,17 +150,14 @@ describe("FileTrie", () => {
const data1 = { const data1 = {
title: "Root", title: "Root",
slug: "index", slug: "index",
filePath: "index.md",
} }
const data2 = { const data2 = {
title: "Test", title: "Test",
slug: "folder/subfolder/test", slug: "folder/subfolder/test",
filePath: "folder/subfolder/test.md",
} }
const data3 = { const data3 = {
title: "Folder Index", title: "Folder Index",
slug: "abc/index", slug: "abc/index",
filePath: "abc/index.md",
} }
trie.add(data1) trie.add(data1)
@ -226,9 +176,9 @@ describe("FileTrie", () => {
describe("sort", () => { describe("sort", () => {
test("should sort nodes according to sort function", () => { test("should sort nodes according to sort function", () => {
const data1 = { title: "A", slug: "a", filePath: "a.md" } const data1 = { title: "A", slug: "a" }
const data2 = { title: "B", slug: "b", filePath: "b.md" } const data2 = { title: "B", slug: "b" }
const data3 = { title: "C", slug: "c", filePath: "c.md" } const data3 = { title: "C", slug: "c" }
trie.add(data3) trie.add(data3)
trie.add(data1) trie.add(data1)

View File

@ -4,7 +4,6 @@ import { FullSlug, joinSegments } from "./path"
interface FileTrieData { interface FileTrieData {
slug: string slug: string
title: string title: string
filePath: string
} }
export class FileTrieNode<T extends FileTrieData = ContentDetails> { export class FileTrieNode<T extends FileTrieData = ContentDetails> {
@ -12,11 +11,6 @@ export class FileTrieNode<T extends FileTrieData = ContentDetails> {
children: Array<FileTrieNode<T>> children: Array<FileTrieNode<T>>
private slugSegments: string[] private slugSegments: string[]
// prefer showing the file path segment over the slug segment
// so that folders that dont have index files can be shown as is
// without dashes in the slug
private fileSegmentHint?: string
private displayNameOverride?: string
data: T | null data: T | null
constructor(segments: string[], data?: T) { constructor(segments: string[], data?: T) {
@ -24,18 +18,10 @@ export class FileTrieNode<T extends FileTrieData = ContentDetails> {
this.slugSegments = segments this.slugSegments = segments
this.data = data ?? null this.data = data ?? null
this.isFolder = false this.isFolder = false
this.displayNameOverride = undefined
} }
get displayName(): string { get displayName(): string {
const nonIndexTitle = this.data?.title === "index" ? undefined : this.data?.title return this.data?.title ?? this.slugSegment ?? ""
return (
this.displayNameOverride ?? nonIndexTitle ?? this.fileSegmentHint ?? this.slugSegment ?? ""
)
}
set displayName(name: string) {
this.displayNameOverride = name
} }
get slug(): FullSlug { get slug(): FullSlug {
@ -77,9 +63,6 @@ export class FileTrieNode<T extends FileTrieData = ContentDetails> {
// recursive case, we are not at the end of the path // recursive case, we are not at the end of the path
const child = const child =
this.children.find((c) => c.slugSegment === segment) ?? this.makeChild(path, undefined) this.children.find((c) => c.slugSegment === segment) ?? this.makeChild(path, undefined)
const fileParts = file.filePath.split("/")
child.fileSegmentHint = fileParts.at(-path.length)
child.insert(path.slice(1), file) child.insert(path.slice(1), file)
} }
} }

View File

@ -105,9 +105,9 @@ ${stylesheet.join("\n\n")}
--highlight: ${theme.colors.lightMode.highlight}; --highlight: ${theme.colors.lightMode.highlight};
--textHighlight: ${theme.colors.lightMode.textHighlight}; --textHighlight: ${theme.colors.lightMode.textHighlight};
--headerFont: "${getFontSpecificationName(theme.typography.header)}", ${DEFAULT_SANS_SERIF}; --headerFont: "${theme.typography.header}", ${DEFAULT_SANS_SERIF};
--bodyFont: "${getFontSpecificationName(theme.typography.body)}", ${DEFAULT_SANS_SERIF}; --bodyFont: "${theme.typography.body}", ${DEFAULT_SANS_SERIF};
--codeFont: "${getFontSpecificationName(theme.typography.code)}", ${DEFAULT_MONO}; --codeFont: "${theme.typography.code}", ${DEFAULT_MONO};
} }
:root[saved-theme="dark"] { :root[saved-theme="dark"] {