mirror of
https://github.com/jackyzha0/quartz.git
synced 2025-12-27 23:04:05 -06:00
feat: add subfolders to folder page
This commit is contained in:
parent
e26448eaf3
commit
405f6f5103
38
quartz/components/FolderList.tsx
Normal file
38
quartz/components/FolderList.tsx
Normal file
@ -0,0 +1,38 @@
|
||||
import path from "path"
|
||||
import { resolveRelative, SimpleSlug } from "../util/path"
|
||||
import { QuartzComponent, QuartzComponentProps } from "./types"
|
||||
|
||||
type Props = {
|
||||
limit?: number
|
||||
} & QuartzComponentProps
|
||||
|
||||
export const FolderList: QuartzComponent = ({ cfg, fileData, allFolders, limit }: Props) => {
|
||||
let list: SimpleSlug[] = allFolders.sort(_alphabetical)
|
||||
if (limit) {
|
||||
list = list.slice(0, limit)
|
||||
}
|
||||
|
||||
return (
|
||||
<ul>
|
||||
{list.map((folderSlug) => {
|
||||
const title = _getTitle(folderSlug)
|
||||
|
||||
return (
|
||||
<li>
|
||||
<a href={resolveRelative(fileData.slug!, folderSlug!)}>{title}</a>
|
||||
</li>
|
||||
)
|
||||
})}
|
||||
</ul>
|
||||
)
|
||||
}
|
||||
|
||||
function _alphabetical(f1: SimpleSlug, f2: SimpleSlug): number {
|
||||
const f1Title = _getTitle(f1)
|
||||
const f2Title = _getTitle(f2)
|
||||
return f1Title.localeCompare(f2Title)
|
||||
}
|
||||
|
||||
function _getTitle(folderSlug: SimpleSlug): string {
|
||||
return folderSlug.split(path.posix.sep).at(-1)!
|
||||
}
|
||||
@ -3,21 +3,25 @@ import path from "path"
|
||||
|
||||
import style from "../styles/listPage.scss"
|
||||
import { PageList, SortFn } from "../PageList"
|
||||
import { stripSlashes, simplifySlug } from "../../util/path"
|
||||
import { FolderList } from "../FolderList"
|
||||
import { stripSlashes, simplifySlug, SimpleSlug, joinSegments } from "../../util/path"
|
||||
import { Root } from "hast"
|
||||
import { htmlToJsx } from "../../util/jsx"
|
||||
import { i18n } from "../../i18n"
|
||||
import { QuartzPluginData } from "../../plugins/vfile"
|
||||
|
||||
interface FolderContentOptions {
|
||||
/**
|
||||
* Whether to display number of folders
|
||||
*/
|
||||
showFolderCount: boolean
|
||||
showSubfolders: boolean
|
||||
sort?: SortFn
|
||||
}
|
||||
|
||||
const defaultOptions: FolderContentOptions = {
|
||||
showFolderCount: true,
|
||||
showSubfolders: true,
|
||||
}
|
||||
|
||||
export default ((opts?: Partial<FolderContentOptions>) => {
|
||||
@ -26,21 +30,40 @@ export default ((opts?: Partial<FolderContentOptions>) => {
|
||||
const FolderContent: QuartzComponent = (props: QuartzComponentProps) => {
|
||||
const { tree, fileData, allFiles, cfg } = props
|
||||
const folderSlug = stripSlashes(simplifySlug(fileData.slug!))
|
||||
const allPagesInFolder = allFiles.filter((file) => {
|
||||
|
||||
const allPagesInFolder: QuartzPluginData[] = []
|
||||
const allSubfolders: Set<SimpleSlug> = new Set()
|
||||
|
||||
allFiles.forEach((file) => {
|
||||
const fileSlug = stripSlashes(simplifySlug(file.slug!))
|
||||
const prefixed = fileSlug.startsWith(folderSlug) && fileSlug !== folderSlug
|
||||
const folderParts = folderSlug.split(path.posix.sep)
|
||||
const fileParts = fileSlug.split(path.posix.sep)
|
||||
const isDirectChild = fileParts.length === folderParts.length + 1
|
||||
return prefixed && isDirectChild
|
||||
|
||||
if (!prefixed) {
|
||||
return
|
||||
}
|
||||
|
||||
if (isDirectChild) {
|
||||
allPagesInFolder.push(file)
|
||||
} else {
|
||||
const folderSlug = joinSegments(...fileParts.slice(0, folderParts.length + 1))
|
||||
allSubfolders.add(folderSlug as SimpleSlug)
|
||||
}
|
||||
})
|
||||
|
||||
const cssClasses: string[] = fileData.frontmatter?.cssclasses ?? []
|
||||
const classes = ["popover-hint", ...cssClasses].join(" ")
|
||||
const listProps = {
|
||||
const pageListProps = {
|
||||
...props,
|
||||
sort: options.sort,
|
||||
allFiles: allPagesInFolder,
|
||||
}
|
||||
const folderListProps = {
|
||||
...props,
|
||||
allFolders: Array.from(allSubfolders.values()),
|
||||
}
|
||||
|
||||
const content =
|
||||
(tree as Root).children.length === 0
|
||||
@ -59,7 +82,15 @@ export default ((opts?: Partial<FolderContentOptions>) => {
|
||||
</p>
|
||||
)}
|
||||
<div>
|
||||
<PageList {...listProps} />
|
||||
<PageList {...pageListProps} />
|
||||
</div>
|
||||
</div>
|
||||
<div class="page-listing">
|
||||
{options.showSubfolders && (
|
||||
<p>{allSubfolders.size === 1 ? "1 subfolder." : `${allSubfolders.size} subfolders.`}</p>
|
||||
)}
|
||||
<div>
|
||||
<FolderList {...folderListProps} />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Loading…
Reference in New Issue
Block a user