Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(explorer): collapsible mobile explorer #1471

Merged
merged 30 commits into from
Feb 3, 2025
Merged
Show file tree
Hide file tree
Changes from 12 commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
a190cba
Rewrite mobile explorer
saberzero1 Oct 1, 2024
139573f
Finished mobile explorer
saberzero1 Oct 1, 2024
836f2a8
Fix folder/tag page
saberzero1 Oct 1, 2024
526e50a
Cleanup
saberzero1 Oct 1, 2024
7d404ac
Combine into single explorer tree
saberzero1 Oct 1, 2024
1e8e3e6
Restore mobile button position
saberzero1 Oct 1, 2024
60aae86
Merge branch 'jackyzha0:v4' into explorer
saberzero1 Oct 3, 2024
ad1a7d7
classNames usage
saberzero1 Oct 3, 2024
4e8e251
Clean up redundant code
saberzero1 Oct 3, 2024
0513ad4
Addressed feedback
saberzero1 Oct 3, 2024
5fd0f17
Cleanup
saberzero1 Oct 3, 2024
356647f
Restore position of functions
saberzero1 Oct 3, 2024
835f6a0
Revert Footer
saberzero1 Oct 3, 2024
26e0b43
Addressed feedback
saberzero1 Oct 3, 2024
40ca67c
Remove usePagePath
saberzero1 Oct 3, 2024
ff9be50
Prettier
saberzero1 Oct 3, 2024
7e41e10
Merge branch 'v4' into explorer
saberzero1 Oct 4, 2024
fda7b66
Update quartz/components/Footer.tsx
saberzero1 Oct 4, 2024
7416415
Merge branch 'v4' into explorer
saberzero1 Oct 9, 2024
316a993
Changed mobile explorer from dropdown to slide-in
saberzero1 Oct 25, 2024
979d653
Remove container div
saberzero1 Oct 26, 2024
90e984e
Restore position
saberzero1 Oct 26, 2024
c2e9477
Slide in + no ugly onload animation on mobile
saberzero1 Oct 26, 2024
8bb32c2
Cleanup
saberzero1 Oct 26, 2024
70cf007
Icon spacing
saberzero1 Nov 2, 2024
9b8dec0
Merge branch 'v4' into explorer
saberzero1 Feb 1, 2025
a1c36ec
SASS styling fixes
saberzero1 Feb 1, 2025
849e8ac
Remove unused parameter
saberzero1 Feb 1, 2025
9786ead
Copilot nitpick
saberzero1 Feb 1, 2025
e31527a
Prefer compatibility
saberzero1 Feb 1, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions quartz.layout.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ export const defaultContentPageLayout: PageLayout = {
Component.MobileOnly(Component.Spacer()),
Component.Search(),
Component.Darkmode(),
Component.DesktopOnly(Component.Explorer()),
Component.Explorer(),
],
right: [
Component.Graph(),
Expand All @@ -44,7 +44,7 @@ export const defaultListPageLayout: PageLayout = {
Component.MobileOnly(Component.Spacer()),
Component.Search(),
Component.Darkmode(),
Component.DesktopOnly(Component.Explorer()),
Component.Explorer(),
],
right: [],
}
106 changes: 71 additions & 35 deletions quartz/components/Explorer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ const defaultOptions = {
folderClickBehavior: "collapse",
folderDefaultState: "collapsed",
useSavedState: true,
usePagePath: false,
mapFn: (node) => {
return node
},
Expand Down Expand Up @@ -46,7 +47,7 @@ export default ((userOpts?: Partial<Options>) => {
let jsonTree: string
let lastBuildId: string = ""

function constructFileTree(allFiles: QuartzPluginData[]) {
function constructFileTree(allFiles: QuartzPluginData[], currentFilePath: string) {
// Construct tree from allFiles
fileTree = new FileNode("")
allFiles.forEach((file) => fileTree.add(file))
Expand All @@ -68,7 +69,10 @@ export default ((userOpts?: Partial<Options>) => {

// Get all folders of tree. Initialize with collapsed state
// Stringify to pass json tree as data attribute ([data-tree])
const folders = fileTree.getFolderPaths(opts.folderDefaultState === "collapsed")
const folders = fileTree.getFolderPaths(
opts.folderDefaultState === "collapsed",
currentFilePath,
)
jsonTree = JSON.stringify(folders)
}

Expand All @@ -81,42 +85,74 @@ export default ((userOpts?: Partial<Options>) => {
}: QuartzComponentProps) => {
if (ctx.buildId !== lastBuildId) {
lastBuildId = ctx.buildId
constructFileTree(allFiles)
constructFileTree(allFiles, (fileData.filePath ?? "").replaceAll(" ", "-"))
}

return (
<div class={classNames(displayClass, "explorer")}>
<button
type="button"
id="explorer"
data-behavior={opts.folderClickBehavior}
data-collapsed={opts.folderDefaultState}
data-savestate={opts.useSavedState}
data-tree={jsonTree}
aria-controls="explorer-content"
aria-expanded={opts.folderDefaultState === "open"}
>
<h2>{opts.title ?? i18n(cfg.locale).components.explorer.title}</h2>
<svg
xmlns="http://www.w3.org/2000/svg"
width="14"
height="14"
viewBox="5 8 14 8"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
class="fold"
<div class="explorer-container">
<div class={classNames(displayClass, "explorer")}>
<button
type="button"
id="mobile-explorer"
class="collapsed"
data-behavior={opts.folderClickBehavior}
data-collapsed={opts.folderDefaultState}
data-savestate={opts.useSavedState}
data-pagepathstate={opts.usePagePath}
data-tree={jsonTree}
data-mobile={true}
aria-controls="explorer-content"
aria-expanded={false}
>
<svg
xmlns="http://www.w3.org/2000/svg"
width="24"
height="24"
viewBox="0 0 24 24"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
class="lucide lucide-menu"
>
<line x1="4" x2="20" y1="12" y2="12" />
<line x1="4" x2="20" y1="6" y2="6" />
<line x1="4" x2="20" y1="18" y2="18" />
</svg>
</button>
<button
type="button"
id="desktop-explorer"
class="title-button"
data-behavior={opts.folderClickBehavior}
data-collapsed={opts.folderDefaultState}
data-savestate={opts.useSavedState}
data-pagepathstate={opts.usePagePath}
data-tree={jsonTree}
data-mobile={false}
aria-controls="explorer-content"
aria-expanded={true}
>
<polyline points="6 9 12 15 18 9"></polyline>
</svg>
</button>
<div id="explorer-content">
<ul class="overflow" id="explorer-ul">
<ExplorerNode node={fileTree} opts={opts} fileData={fileData} />
<li id="explorer-end" />
</ul>
<h2>{opts.title ?? i18n(cfg.locale).components.explorer.title}</h2>
<svg
xmlns="http://www.w3.org/2000/svg"
width="14"
height="14"
viewBox="5 8 14 8"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
class="fold"
>
<polyline points="6 9 12 15 18 9"></polyline>
</svg>
</button>
<div id="explorer-content" class="">
<ul class="overflow" id="explorer-ul">
<ExplorerNode node={fileTree} opts={opts} fileData={fileData} />
<li id="explorer-end" />
</ul>
</div>
</div>
</div>
)
Expand Down
4 changes: 3 additions & 1 deletion quartz/components/ExplorerNode.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ export interface Options {
folderDefaultState: "collapsed" | "open"
folderClickBehavior: "collapse" | "link"
useSavedState: boolean
usePagePath: boolean
sortFn: (a: FileNode, b: FileNode) => number
filterFn: (node: FileNode) => boolean
mapFn: (node: FileNode) => void
Expand Down Expand Up @@ -124,9 +125,10 @@ export class FileNode {
* Get folder representation with state of tree.
* Intended to only be called on root node before changes to the tree are made
* @param collapsed default state of folders (collapsed by default or not)
* @param currentFile current file
* @returns array containing folder state for tree
*/
getFolderPaths(collapsed: boolean): FolderState[] {
getFolderPaths(collapsed: boolean, currentFile: string): FolderState[] {
const folderPaths: FolderState[] = []

const traverse = (node: FileNode, currentPath: string) => {
Expand Down
3 changes: 2 additions & 1 deletion quartz/components/Footer.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { QuartzComponent, QuartzComponentConstructor, QuartzComponentProps } from "./types"
import style from "./styles/footer.scss"
import { version } from "../../package.json"
import { classNames } from "../util/lang"
import { i18n } from "../i18n"

interface Options {
Expand All @@ -12,7 +13,7 @@ export default ((opts?: Options) => {
const year = new Date().getFullYear()
const links = opts?.links ?? []
return (
<footer class={`${displayClass ?? ""}`}>
<footer class={classNames(displayClass)}>
<p>
{i18n(cfg.locale).components.footer.createdWith}{" "}
<a href="https://quartz.jzhao.xyz/">Quartz v{version}</a> © {year}
Expand Down
Loading