// Nothing yet import { QuartzComponent, QuartzComponentConstructor, QuartzComponentProps } from "../components/types" import overlayexplorerStyle from "./styles/overlayexplorer.scss" // @ts-ignore import script from "./scripts/overlayexplorer.inline" import { FileNode, Options } from "../components/ExplorerNode" import { QuartzPluginData } from "../plugins/vfile" import { classNames } from "../util/lang" import { i18n } from "../i18n" import { joinSegments, resolveRelative } from "../util/path" interface OlOptions extends Omit { folderClickBehavior: "collapse" | "link" | "mixed" } const defaultOptions = { folderClickBehavior: "mixed", folderDefaultState: "collapsed", useSavedState: true, mapFn: (node) => { return node }, sortFn: (a, b) => { // Sort order: folders first, then files. Sort folders and files alphabetically if ((!a.file && !b.file) || (a.file && b.file)) { // numeric: true: Whether numeric collation should be used, such that "1" < "2" < "10" // sensitivity: "base": Only strings that differ in base letters compare as unequal. Examples: a ≠ b, a = á, a = A return a.displayName.localeCompare(b.displayName, undefined, { numeric: true, sensitivity: "base", }) } if (a.file && !b.file) { return 1 } else { return -1 } }, filterFn: (node) => node.name !== "tags", order: ["filter", "map", "sort"], } satisfies OlOptions type OlExplorerNodeProps = { node: FileNode opts: OlOptions fileData: QuartzPluginData fullPath?: string } function OverlayExplorerNode({node, opts, fullPath, fileData}: OlExplorerNodeProps) { // Calculate current folderPath const folderPath = node.name !== "" ? joinSegments(fullPath ?? "", node.name) : "" const href = resolveRelative(fileData.slug!, folderPath as SimpleSlug) + "/" return ( <> {node.file ? (
  • {node.displayName}
  • ) : (
  • {node.name !== "" && (
    {opts.folderClickBehavior === "link" ? ( {node.displayName} ) : ( <> {opts.folderClickBehavior === "mixed" && ( )} )}
    )}
      {node.children.map((childNode, i) => ( ))}
  • )} ) } export default ((userOpts?: Partial) => { // Parse config const opts: OlOptions = { ...defaultOptions, ...userOpts } // memoized let fileTree: FileNode let lastBuildId: string = "" function constructFileTree(allFiles: QuartzPluginData[]) { // Construct tree from allFiles fileTree = new FileNode("") allFiles.forEach((file) => fileTree.add(file)) // Execute all functions (sort, filter, map) that were provided (if none were provided, only default "sort" is applied) if (opts.order) { // Order is important, use loop with index instead of order.map() for (let i = 0; i < opts.order.length; i++) { const functionName = opts.order[i] if (functionName === "map") { fileTree.map(opts.mapFn) } else if (functionName === "sort") { fileTree.sort(opts.sortFn) } else if (functionName === "filter") { fileTree.filter(opts.filterFn) } } } } const OverlayExplorer: QuartzComponent = ({ ctx, cfg, allFiles, displayClass, fileData, }: QuartzComponentProps) => { if (ctx.buildId !== lastBuildId) { lastBuildId = ctx.buildId constructFileTree(allFiles) } return (
    ) } OverlayExplorer.css = overlayexplorerStyle OverlayExplorer.afterDOMLoaded = script return OverlayExplorer }) satisfies QuartzComponentConstructor