mirror of
https://github.com/jackyzha0/quartz.git
synced 2026-02-04 06:25:41 -06:00
style: Fixed styling according to prettier
This commit is contained in:
parent
34ca053936
commit
15ff47b82d
@ -69,8 +69,8 @@ Multiple parents:
|
|||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
parent:
|
parent:
|
||||||
- [[Basics]]
|
- [[Basics]]
|
||||||
- [[Reference]]
|
- [[Reference]]
|
||||||
```
|
```
|
||||||
|
|
||||||
### Configuration
|
### Configuration
|
||||||
@ -81,10 +81,10 @@ Default configuration:
|
|||||||
|
|
||||||
```ts
|
```ts
|
||||||
Component.ParentBreadcrumbs({
|
Component.ParentBreadcrumbs({
|
||||||
spacerSymbol: "❯", // symbol displayed between breadcrumb levels
|
spacerSymbol: "❯", // symbol displayed between breadcrumb levels
|
||||||
rootName: "Home", // label for the root (index) page
|
rootName: "Home", // label for the root (index) page
|
||||||
resolveFrontmatterTitle: true, // use frontmatter.title instead of slug
|
resolveFrontmatterTitle: true, // use frontmatter.title instead of slug
|
||||||
parentKey: "parent", // frontmatter key used to resolve parents
|
parentKey: "parent", // frontmatter key used to resolve parents
|
||||||
})
|
})
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
118
quartz.layout.ts
118
quartz.layout.ts
@ -1,68 +1,68 @@
|
|||||||
import { PageLayout, SharedLayout } from "./quartz/cfg";
|
import { PageLayout, SharedLayout } from "./quartz/cfg"
|
||||||
import * as Component from "./quartz/components";
|
import * as Component from "./quartz/components"
|
||||||
|
|
||||||
// components shared across all pages
|
// components shared across all pages
|
||||||
export const sharedPageComponents: SharedLayout = {
|
export const sharedPageComponents: SharedLayout = {
|
||||||
head: Component.Head(),
|
head: Component.Head(),
|
||||||
header: [],
|
header: [],
|
||||||
afterBody: [],
|
afterBody: [],
|
||||||
footer: Component.Footer({
|
footer: Component.Footer({
|
||||||
links: {
|
links: {
|
||||||
GitHub: "https://github.com/jackyzha0/quartz",
|
GitHub: "https://github.com/jackyzha0/quartz",
|
||||||
"Discord Community": "https://discord.gg/cRFFHYye7t",
|
"Discord Community": "https://discord.gg/cRFFHYye7t",
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
};
|
}
|
||||||
|
|
||||||
// components for pages that display a single page (e.g. a single note)
|
// components for pages that display a single page (e.g. a single note)
|
||||||
export const defaultContentPageLayout: PageLayout = {
|
export const defaultContentPageLayout: PageLayout = {
|
||||||
beforeBody: [
|
beforeBody: [
|
||||||
Component.ConditionalRender({
|
Component.ConditionalRender({
|
||||||
component: Component.ParentBreadcrumbs(),
|
component: Component.ParentBreadcrumbs(),
|
||||||
condition: (page) => page.fileData.slug !== "index",
|
condition: (page) => page.fileData.slug !== "index",
|
||||||
}),
|
}),
|
||||||
Component.ArticleTitle(),
|
Component.ArticleTitle(),
|
||||||
Component.ContentMeta(),
|
Component.ContentMeta(),
|
||||||
Component.TagList(),
|
Component.TagList(),
|
||||||
],
|
],
|
||||||
left: [
|
left: [
|
||||||
Component.PageTitle(),
|
Component.PageTitle(),
|
||||||
Component.MobileOnly(Component.Spacer()),
|
Component.MobileOnly(Component.Spacer()),
|
||||||
Component.Flex({
|
Component.Flex({
|
||||||
components: [
|
components: [
|
||||||
{
|
{
|
||||||
Component: Component.Search(),
|
Component: Component.Search(),
|
||||||
grow: true,
|
grow: true,
|
||||||
},
|
},
|
||||||
{ Component: Component.Darkmode() },
|
{ Component: Component.Darkmode() },
|
||||||
{ Component: Component.ReaderMode() },
|
{ Component: Component.ReaderMode() },
|
||||||
],
|
],
|
||||||
}),
|
}),
|
||||||
Component.Explorer(),
|
Component.Explorer(),
|
||||||
],
|
],
|
||||||
right: [
|
right: [
|
||||||
Component.Graph(),
|
Component.Graph(),
|
||||||
Component.DesktopOnly(Component.TableOfContents()),
|
Component.DesktopOnly(Component.TableOfContents()),
|
||||||
Component.Backlinks(),
|
Component.Backlinks(),
|
||||||
],
|
],
|
||||||
};
|
}
|
||||||
|
|
||||||
// components for pages that display lists of pages (e.g. tags or folders)
|
// components for pages that display lists of pages (e.g. tags or folders)
|
||||||
export const defaultListPageLayout: PageLayout = {
|
export const defaultListPageLayout: PageLayout = {
|
||||||
beforeBody: [Component.Breadcrumbs(), Component.ArticleTitle(), Component.ContentMeta()],
|
beforeBody: [Component.Breadcrumbs(), Component.ArticleTitle(), Component.ContentMeta()],
|
||||||
left: [
|
left: [
|
||||||
Component.PageTitle(),
|
Component.PageTitle(),
|
||||||
Component.MobileOnly(Component.Spacer()),
|
Component.MobileOnly(Component.Spacer()),
|
||||||
Component.Flex({
|
Component.Flex({
|
||||||
components: [
|
components: [
|
||||||
{
|
{
|
||||||
Component: Component.Search(),
|
Component: Component.Search(),
|
||||||
grow: true,
|
grow: true,
|
||||||
},
|
},
|
||||||
{ Component: Component.Darkmode() },
|
{ Component: Component.Darkmode() },
|
||||||
],
|
],
|
||||||
}),
|
}),
|
||||||
Component.Explorer(),
|
Component.Explorer(),
|
||||||
],
|
],
|
||||||
right: [],
|
right: [],
|
||||||
};
|
}
|
||||||
|
|||||||
@ -1,125 +1,126 @@
|
|||||||
import { QuartzComponent, QuartzComponentConstructor, QuartzComponentProps } from "./types";
|
import { QuartzComponent, QuartzComponentConstructor, QuartzComponentProps } from "./types"
|
||||||
import { QuartzPluginData } from "../plugins/vfile";
|
import { QuartzPluginData } from "../plugins/vfile"
|
||||||
import { classNames } from "../util/lang";
|
import { classNames } from "../util/lang"
|
||||||
import { resolveRelative, simplifySlug, FullSlug, SimpleSlug } from "../util/path";
|
import { resolveRelative, simplifySlug, FullSlug, SimpleSlug } from "../util/path"
|
||||||
import style from "./styles/breadcrumbs.scss";
|
import style from "./styles/breadcrumbs.scss"
|
||||||
|
|
||||||
interface ParentBreadcrumbsOptions {
|
interface ParentBreadcrumbsOptions {
|
||||||
spacerSymbol?: string;
|
spacerSymbol?: string
|
||||||
rootName?: string;
|
rootName?: string
|
||||||
resolveFrontmatterTitle?: boolean;
|
resolveFrontmatterTitle?: boolean
|
||||||
frontmatterProp?: string,
|
frontmatterProp?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
const defaultOptions: ParentBreadcrumbsOptions = {
|
const defaultOptions: ParentBreadcrumbsOptions = {
|
||||||
spacerSymbol: "❯",
|
spacerSymbol: "❯",
|
||||||
rootName: "Home",
|
rootName: "Home",
|
||||||
resolveFrontmatterTitle: true,
|
resolveFrontmatterTitle: true,
|
||||||
frontmatterProp: "parent",
|
frontmatterProp: "parent",
|
||||||
};
|
}
|
||||||
|
|
||||||
export default ((opts?: ParentBreadcrumbsOptions) => {
|
export default ((opts?: ParentBreadcrumbsOptions) => {
|
||||||
const options = { ...defaultOptions, ...opts };
|
const options = { ...defaultOptions, ...opts }
|
||||||
const parentKey = options.frontmatterProp;
|
const parentKey = options.frontmatterProp
|
||||||
|
|
||||||
const ParentBreadcrumbs: QuartzComponent = ({
|
const ParentBreadcrumbs: QuartzComponent = ({
|
||||||
fileData,
|
fileData,
|
||||||
allFiles,
|
allFiles,
|
||||||
displayClass,
|
displayClass,
|
||||||
}: QuartzComponentProps) => {
|
}: QuartzComponentProps) => {
|
||||||
|
const parseWikiLink = (content: string): string => {
|
||||||
|
if (!content) return ""
|
||||||
|
let clean = content.trim().replace(/^["']|["']$/g, "")
|
||||||
|
clean = clean.replace(/^\[\[|\]\]$/g, "")
|
||||||
|
return clean.split("|")[0]
|
||||||
|
}
|
||||||
|
|
||||||
const parseWikiLink = (content: string): string => {
|
const findFile = (name: string) => {
|
||||||
if (!content) return "";
|
const targetSlug = simplifySlug(name as FullSlug)
|
||||||
let clean = content.trim().replace(/^["']|["']$/g, "");
|
return allFiles.find((f: QuartzPluginData) => {
|
||||||
clean = clean.replace(/^\[\[|\]\]$/g, "");
|
const fSlug = simplifySlug(f.slug!)
|
||||||
return clean.split("|")[0];
|
return fSlug === targetSlug || fSlug.endsWith(targetSlug) || f.frontmatter?.title === name
|
||||||
};
|
})
|
||||||
|
}
|
||||||
|
|
||||||
const findFile = (name: string) => {
|
type BreadcrumbNode = { displayName: string; path: string }
|
||||||
const targetSlug = simplifySlug(name as FullSlug);
|
const crumbs: Array<BreadcrumbNode[]> = []
|
||||||
return allFiles.find((f: QuartzPluginData) => {
|
|
||||||
const fSlug = simplifySlug(f.slug!);
|
|
||||||
return fSlug === targetSlug || fSlug.endsWith(targetSlug) || f.frontmatter?.title === name;
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
type BreadcrumbNode = { displayName: string; path: string; };
|
let current = fileData
|
||||||
const crumbs: Array<BreadcrumbNode[]> = [];
|
const visited = new Set<string>()
|
||||||
|
if (current.slug) visited.add(current.slug)
|
||||||
|
|
||||||
let current = fileData;
|
while (current && current.frontmatter?.[parentKey!]) {
|
||||||
const visited = new Set<string>();
|
const rawParent = current.frontmatter[parentKey!]
|
||||||
if (current.slug) visited.add(current.slug);
|
const parentList = Array.isArray(rawParent) ? rawParent : [rawParent]
|
||||||
|
|
||||||
while (current && current.frontmatter?.[parentKey!]) {
|
const currentLevelNodes: BreadcrumbNode[] = []
|
||||||
const rawParent = current.frontmatter[parentKey!];
|
let nextParent: QuartzPluginData | undefined = undefined
|
||||||
const parentList = Array.isArray(rawParent) ? rawParent : [rawParent];
|
|
||||||
|
|
||||||
const currentLevelNodes: BreadcrumbNode[] = [];
|
for (const p of parentList) {
|
||||||
let nextParent: QuartzPluginData | undefined = undefined;
|
const linkStr = parseWikiLink(p as string)
|
||||||
|
const parentFile = findFile(linkStr)
|
||||||
|
|
||||||
for (const p of parentList) {
|
if (parentFile && parentFile.slug) {
|
||||||
const linkStr = parseWikiLink(p as string);
|
currentLevelNodes.push({
|
||||||
const parentFile = findFile(linkStr);
|
displayName: options.resolveFrontmatterTitle
|
||||||
|
? (parentFile.frontmatter?.title ?? parentFile.slug)
|
||||||
|
: parentFile.slug,
|
||||||
|
path: resolveRelative(fileData.slug!, parentFile.slug!),
|
||||||
|
})
|
||||||
|
|
||||||
if (parentFile && parentFile.slug) {
|
if (!nextParent && !visited.has(parentFile.slug)) {
|
||||||
currentLevelNodes.push({
|
nextParent = parentFile
|
||||||
displayName: options.resolveFrontmatterTitle
|
}
|
||||||
? parentFile.frontmatter?.title ?? parentFile.slug
|
}
|
||||||
: parentFile.slug,
|
}
|
||||||
path: resolveRelative(fileData.slug!, parentFile.slug!)
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!nextParent && !visited.has(parentFile.slug)) {
|
if (currentLevelNodes.length > 0) {
|
||||||
nextParent = parentFile;
|
crumbs.push(currentLevelNodes)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (currentLevelNodes.length > 0) {
|
if (nextParent) {
|
||||||
crumbs.push(currentLevelNodes);
|
visited.add(nextParent.slug!)
|
||||||
}
|
current = nextParent
|
||||||
|
} else {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (nextParent) {
|
if (current.slug !== "index") {
|
||||||
visited.add(nextParent.slug!);
|
crumbs.push([
|
||||||
current = nextParent;
|
{
|
||||||
} else {
|
displayName: options.rootName!,
|
||||||
break;
|
path: resolveRelative(fileData.slug!, "index" as SimpleSlug),
|
||||||
}
|
},
|
||||||
}
|
])
|
||||||
|
}
|
||||||
|
|
||||||
if (current.slug !== "index") {
|
crumbs.reverse()
|
||||||
crumbs.push([{
|
|
||||||
displayName: options.rootName!,
|
|
||||||
path: resolveRelative(fileData.slug!, "index" as SimpleSlug)
|
|
||||||
}]);
|
|
||||||
}
|
|
||||||
|
|
||||||
crumbs.reverse();
|
if (crumbs.length === 0 && fileData.slug === "index") {
|
||||||
|
return <></>
|
||||||
|
}
|
||||||
|
|
||||||
if (crumbs.length === 0 && fileData.slug === "index") {
|
return (
|
||||||
return <></>;
|
<nav class={classNames(displayClass, "breadcrumb-container")} aria-label="breadcrumbs">
|
||||||
}
|
{crumbs.map((crumbLevel, levelIndex) => (
|
||||||
|
<div class="breadcrumb-element">
|
||||||
|
{crumbLevel.map((node, nodeIndex) => (
|
||||||
|
<>
|
||||||
|
<a href={node.path}>{node.displayName}</a>
|
||||||
|
{nodeIndex < crumbLevel.length - 1 && <span style={{ opacity: 0.5 }}> / </span>}
|
||||||
|
</>
|
||||||
|
))}
|
||||||
|
{levelIndex !== crumbs.length && <p>{options.spacerSymbol}</p>}
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
<div class="breadcrumb-element">
|
||||||
|
<p>{fileData.frontmatter?.title}</p>
|
||||||
|
</div>
|
||||||
|
</nav>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
ParentBreadcrumbs.css = style
|
||||||
<nav class={classNames(displayClass, "breadcrumb-container")} aria-label="breadcrumbs">
|
return ParentBreadcrumbs
|
||||||
{crumbs.map((crumbLevel, levelIndex) => (
|
}) satisfies QuartzComponentConstructor
|
||||||
<div class="breadcrumb-element">
|
|
||||||
{crumbLevel.map((node, nodeIndex) => (
|
|
||||||
<>
|
|
||||||
<a href={node.path}>{node.displayName}</a>
|
|
||||||
{nodeIndex < crumbLevel.length - 1 && <span style={{ opacity: 0.5 }}> / </span>}
|
|
||||||
</>
|
|
||||||
))}
|
|
||||||
{levelIndex !== crumbs.length && <p>{options.spacerSymbol}</p>}
|
|
||||||
</div>
|
|
||||||
))}
|
|
||||||
<div class="breadcrumb-element">
|
|
||||||
<p>{fileData.frontmatter?.title}</p>
|
|
||||||
</div>
|
|
||||||
</nav>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
ParentBreadcrumbs.css = style;
|
|
||||||
return ParentBreadcrumbs;
|
|
||||||
}) satisfies QuartzComponentConstructor;
|
|
||||||
|
|||||||
@ -1,55 +1,55 @@
|
|||||||
import Content from "./pages/Content";
|
import Content from "./pages/Content"
|
||||||
import TagContent from "./pages/TagContent";
|
import TagContent from "./pages/TagContent"
|
||||||
import FolderContent from "./pages/FolderContent";
|
import FolderContent from "./pages/FolderContent"
|
||||||
import NotFound from "./pages/404";
|
import NotFound from "./pages/404"
|
||||||
import ArticleTitle from "./ArticleTitle";
|
import ArticleTitle from "./ArticleTitle"
|
||||||
import Darkmode from "./Darkmode";
|
import Darkmode from "./Darkmode"
|
||||||
import ReaderMode from "./ReaderMode";
|
import ReaderMode from "./ReaderMode"
|
||||||
import Head from "./Head";
|
import Head from "./Head"
|
||||||
import PageTitle from "./PageTitle";
|
import PageTitle from "./PageTitle"
|
||||||
import ContentMeta from "./ContentMeta";
|
import ContentMeta from "./ContentMeta"
|
||||||
import Spacer from "./Spacer";
|
import Spacer from "./Spacer"
|
||||||
import TableOfContents from "./TableOfContents";
|
import TableOfContents from "./TableOfContents"
|
||||||
import Explorer from "./Explorer";
|
import Explorer from "./Explorer"
|
||||||
import TagList from "./TagList";
|
import TagList from "./TagList"
|
||||||
import Graph from "./Graph";
|
import Graph from "./Graph"
|
||||||
import Backlinks from "./Backlinks";
|
import Backlinks from "./Backlinks"
|
||||||
import Search from "./Search";
|
import Search from "./Search"
|
||||||
import Footer from "./Footer";
|
import Footer from "./Footer"
|
||||||
import DesktopOnly from "./DesktopOnly";
|
import DesktopOnly from "./DesktopOnly"
|
||||||
import MobileOnly from "./MobileOnly";
|
import MobileOnly from "./MobileOnly"
|
||||||
import RecentNotes from "./RecentNotes";
|
import RecentNotes from "./RecentNotes"
|
||||||
import Breadcrumbs from "./Breadcrumbs";
|
import Breadcrumbs from "./Breadcrumbs"
|
||||||
import Comments from "./Comments";
|
import Comments from "./Comments"
|
||||||
import Flex from "./Flex";
|
import Flex from "./Flex"
|
||||||
import ConditionalRender from "./ConditionalRender";
|
import ConditionalRender from "./ConditionalRender"
|
||||||
import ParentBreadcrumbs from "./ParentBreadcrumbs";
|
import ParentBreadcrumbs from "./ParentBreadcrumbs"
|
||||||
|
|
||||||
export {
|
export {
|
||||||
ParentBreadcrumbs,
|
ParentBreadcrumbs,
|
||||||
ArticleTitle,
|
ArticleTitle,
|
||||||
Content,
|
Content,
|
||||||
TagContent,
|
TagContent,
|
||||||
FolderContent,
|
FolderContent,
|
||||||
Darkmode,
|
Darkmode,
|
||||||
ReaderMode,
|
ReaderMode,
|
||||||
Head,
|
Head,
|
||||||
PageTitle,
|
PageTitle,
|
||||||
ContentMeta,
|
ContentMeta,
|
||||||
Spacer,
|
Spacer,
|
||||||
TableOfContents,
|
TableOfContents,
|
||||||
Explorer,
|
Explorer,
|
||||||
TagList,
|
TagList,
|
||||||
Graph,
|
Graph,
|
||||||
Backlinks,
|
Backlinks,
|
||||||
Search,
|
Search,
|
||||||
Footer,
|
Footer,
|
||||||
DesktopOnly,
|
DesktopOnly,
|
||||||
MobileOnly,
|
MobileOnly,
|
||||||
RecentNotes,
|
RecentNotes,
|
||||||
NotFound,
|
NotFound,
|
||||||
Breadcrumbs,
|
Breadcrumbs,
|
||||||
Comments,
|
Comments,
|
||||||
Flex,
|
Flex,
|
||||||
ConditionalRender,
|
ConditionalRender,
|
||||||
};
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user