import { QuartzComponentConstructor, QuartzComponentProps } from "./types" import explorerStyle from "./styles/explorer.scss" // @ts-ignore import script from "./scripts/explorer.inline" import { ExplorerNode, FileNode, Options } from "./ExplorerNode" import { QuartzPluginData } from "../plugins/vfile" // Options interface defined in `ExplorerNode` to avoid circular dependency const defaultOptions = { title: "Explorer", folderClickBehavior: "collapse", 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 Options export default ((userOpts?: Partial) => { // Parse config const opts: Options = { ...defaultOptions, ...userOpts } // memoized let fileTree: FileNode let jsonTree: string function constructFileTree(allFiles: QuartzPluginData[]) { if (fileTree) { return } // 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) } } } // 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") jsonTree = JSON.stringify(folders) } function Explorer({ allFiles, displayClass, fileData }: QuartzComponentProps) { constructFileTree(allFiles) return (
) } Explorer.css = explorerStyle Explorer.afterDOMLoaded = script return Explorer }) satisfies QuartzComponentConstructor