mirror of
https://github.com/quartz-community/breadcrumbs.git
synced 2026-07-22 02:50:29 +00:00
chore: commit dist/ and remove prepare script
Pre-built output is now committed to the repository so that Quartz can skip the build step during plugin installation. The prepare script is removed to prevent redundant builds when installing from npm/git.
This commit is contained in:
parent
a188cf8182
commit
3ae8c2fb1a
9 changed files with 415 additions and 6 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -4,7 +4,6 @@ node_modules/
|
|||
.pnp.js
|
||||
|
||||
# Build output
|
||||
dist/
|
||||
build/
|
||||
*.tsbuildinfo
|
||||
|
||||
|
|
|
|||
2
dist/components/index.d.ts
vendored
Normal file
2
dist/components/index.d.ts
vendored
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
export { BreadcrumbOptions, Breadcrumbs } from '../index.js';
|
||||
import '@quartz-community/types';
|
||||
196
dist/components/index.js
vendored
Normal file
196
dist/components/index.js
vendored
Normal file
|
|
@ -0,0 +1,196 @@
|
|||
import { simplifySlug as simplifySlug$1, joinSegments } from '@quartz-community/utils';
|
||||
import { jsx, jsxs } from 'preact/jsx-runtime';
|
||||
|
||||
// src/util/lang.ts
|
||||
function classNames(...classes) {
|
||||
return classes.filter(Boolean).join(" ");
|
||||
}
|
||||
function simplifySlug(fp) {
|
||||
return simplifySlug$1(fp);
|
||||
}
|
||||
function resolveRelative(current, target) {
|
||||
const simplified = simplifySlug(target);
|
||||
const rootPath = pathToRoot(current);
|
||||
return joinSegments(rootPath, simplified);
|
||||
}
|
||||
function pathToRoot(slug) {
|
||||
let rootPath = slug.split("/").filter((x) => x !== "").slice(0, -1).map((_) => "..").join("/");
|
||||
if (rootPath.length === 0) {
|
||||
rootPath = ".";
|
||||
}
|
||||
return rootPath;
|
||||
}
|
||||
var FileTrieNode = class _FileTrieNode {
|
||||
isFolder;
|
||||
children;
|
||||
slugSegments;
|
||||
fileSegmentHint;
|
||||
displayNameOverride;
|
||||
data;
|
||||
constructor(segments, data) {
|
||||
this.children = [];
|
||||
this.slugSegments = segments;
|
||||
this.data = data ?? null;
|
||||
this.isFolder = false;
|
||||
this.displayNameOverride = void 0;
|
||||
}
|
||||
get displayName() {
|
||||
const nonIndexTitle = this.data?.title === "index" ? void 0 : this.data?.title;
|
||||
return this.displayNameOverride ?? nonIndexTitle ?? this.fileSegmentHint ?? this.slugSegment ?? "";
|
||||
}
|
||||
set displayName(name) {
|
||||
this.displayNameOverride = name;
|
||||
}
|
||||
get slug() {
|
||||
const path = joinSegments(...this.slugSegments);
|
||||
if (this.isFolder) {
|
||||
return joinSegments(path, "index");
|
||||
}
|
||||
return path;
|
||||
}
|
||||
get slugSegment() {
|
||||
return this.slugSegments[this.slugSegments.length - 1] ?? "";
|
||||
}
|
||||
makeChild(path, file) {
|
||||
const nextSegment = path[0];
|
||||
if (!nextSegment) {
|
||||
throw new Error("path is empty");
|
||||
}
|
||||
const fullPath = [...this.slugSegments, nextSegment];
|
||||
const child = new _FileTrieNode(fullPath, file);
|
||||
this.children.push(child);
|
||||
return child;
|
||||
}
|
||||
insert(path, file) {
|
||||
if (path.length === 0) {
|
||||
throw new Error("path is empty");
|
||||
}
|
||||
this.isFolder = true;
|
||||
const segment = path[0];
|
||||
if (!segment) {
|
||||
throw new Error("path is empty");
|
||||
}
|
||||
if (path.length === 1) {
|
||||
if (segment === "index") {
|
||||
this.data ??= file;
|
||||
} else {
|
||||
this.makeChild(path, file);
|
||||
}
|
||||
} else if (path.length > 1) {
|
||||
const child = this.children.find((c) => c.slugSegment === segment) ?? this.makeChild(path, void 0);
|
||||
const fileParts = file.filePath.split("/");
|
||||
const hint = fileParts.at(-path.length);
|
||||
if (hint) {
|
||||
child.fileSegmentHint = hint;
|
||||
}
|
||||
child.insert(path.slice(1), file);
|
||||
}
|
||||
}
|
||||
add(file) {
|
||||
this.insert(file.slug.split("/"), file);
|
||||
}
|
||||
findNode(path) {
|
||||
if (path.length === 0 || path.length === 1 && path[0] === "index") {
|
||||
return this;
|
||||
}
|
||||
return this.children.find((c) => c.slugSegment === path[0])?.findNode(path.slice(1));
|
||||
}
|
||||
ancestryChain(path) {
|
||||
if (path.length === 0 || path.length === 1 && path[0] === "index") {
|
||||
return [this];
|
||||
}
|
||||
const child = this.children.find((c) => c.slugSegment === path[0]);
|
||||
if (!child) {
|
||||
return void 0;
|
||||
}
|
||||
const childPath = child.ancestryChain(path.slice(1));
|
||||
if (!childPath) {
|
||||
return void 0;
|
||||
}
|
||||
return [this, ...childPath];
|
||||
}
|
||||
filter(filterFn) {
|
||||
this.children = this.children.filter(filterFn);
|
||||
this.children.forEach((child) => child.filter(filterFn));
|
||||
}
|
||||
map(mapFn) {
|
||||
mapFn(this);
|
||||
this.children.forEach((child) => child.map(mapFn));
|
||||
}
|
||||
sort(sortFn) {
|
||||
this.children = this.children.sort(sortFn);
|
||||
this.children.forEach((e) => e.sort(sortFn));
|
||||
}
|
||||
};
|
||||
function trieFromAllFiles(allFiles) {
|
||||
const trie = new FileTrieNode([]);
|
||||
allFiles.forEach((file) => {
|
||||
if (file.frontmatter) {
|
||||
trie.add({
|
||||
slug: file.slug,
|
||||
title: file.frontmatter.title ?? "",
|
||||
filePath: file.filePath
|
||||
});
|
||||
}
|
||||
});
|
||||
return trie;
|
||||
}
|
||||
|
||||
// src/components/styles/breadcrumbs.scss
|
||||
var breadcrumbs_default = ".breadcrumb-container {\n margin: 0;\n margin-top: 0.75rem;\n padding: 0;\n display: flex;\n flex-direction: row;\n flex-wrap: wrap;\n gap: 0.5rem;\n}\n\n.breadcrumb-element p {\n margin: 0;\n margin-left: 0.5rem;\n padding: 0;\n line-height: normal;\n}\n.breadcrumb-element {\n display: flex;\n flex-direction: row;\n align-items: center;\n justify-content: center;\n}";
|
||||
var defaultOptions = {
|
||||
spacerSymbol: "\u276F",
|
||||
rootName: "Home",
|
||||
resolveFrontmatterTitle: true,
|
||||
showCurrentPage: true
|
||||
};
|
||||
function formatCrumb(displayName, baseSlug, currentSlug) {
|
||||
return {
|
||||
displayName: displayName.replaceAll("-", " "),
|
||||
path: resolveRelative(baseSlug, currentSlug)
|
||||
};
|
||||
}
|
||||
var Breadcrumbs_default = ((opts) => {
|
||||
const options = { ...defaultOptions, ...opts };
|
||||
const Breadcrumbs = ({
|
||||
fileData,
|
||||
allFiles,
|
||||
displayClass,
|
||||
ctx
|
||||
}) => {
|
||||
const typedCtx = ctx ?? {};
|
||||
typedCtx.trie ??= trieFromAllFiles(
|
||||
allFiles
|
||||
);
|
||||
const trie = typedCtx.trie;
|
||||
const slug = fileData.slug;
|
||||
const slugParts = slug.split("/");
|
||||
const pathNodes = trie.ancestryChain(slugParts);
|
||||
if (!pathNodes) {
|
||||
return null;
|
||||
}
|
||||
const crumbs = pathNodes.map((node, idx) => {
|
||||
const crumb = formatCrumb(node.displayName, slug, simplifySlug(node.slug));
|
||||
if (idx === 0) {
|
||||
crumb.displayName = options.rootName;
|
||||
}
|
||||
if (idx === pathNodes.length - 1) {
|
||||
crumb.path = "";
|
||||
}
|
||||
return crumb;
|
||||
});
|
||||
if (!options.showCurrentPage) {
|
||||
crumbs.pop();
|
||||
}
|
||||
return /* @__PURE__ */ jsx("nav", { class: classNames(displayClass, "breadcrumb-container"), "aria-label": "breadcrumbs", children: crumbs.map((crumb, index) => /* @__PURE__ */ jsxs("div", { class: "breadcrumb-element", children: [
|
||||
/* @__PURE__ */ jsx("a", { href: crumb.path, children: crumb.displayName }),
|
||||
index !== crumbs.length - 1 && /* @__PURE__ */ jsx("p", { children: ` ${options.spacerSymbol} ` })
|
||||
] })) });
|
||||
};
|
||||
Breadcrumbs.css = breadcrumbs_default;
|
||||
return Breadcrumbs;
|
||||
});
|
||||
|
||||
export { Breadcrumbs_default as Breadcrumbs };
|
||||
//# sourceMappingURL=index.js.map
|
||||
//# sourceMappingURL=index.js.map
|
||||
1
dist/components/index.js.map
vendored
Normal file
1
dist/components/index.js.map
vendored
Normal file
File diff suppressed because one or more lines are too long
16
dist/index.d.ts
vendored
Normal file
16
dist/index.d.ts
vendored
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
import { QuartzComponent } from '@quartz-community/types';
|
||||
export { QuartzComponent, QuartzComponentProps, StringResource } from '@quartz-community/types';
|
||||
|
||||
interface BreadcrumbOptions {
|
||||
/** Symbol between crumbs */
|
||||
spacerSymbol: string;
|
||||
/** Name of first crumb */
|
||||
rootName: string;
|
||||
/** Whether to look up frontmatter title for folders */
|
||||
resolveFrontmatterTitle: boolean;
|
||||
/** Whether to display the current page in the breadcrumbs */
|
||||
showCurrentPage: boolean;
|
||||
}
|
||||
declare const _default: (opts?: Partial<BreadcrumbOptions>) => QuartzComponent;
|
||||
|
||||
export { type BreadcrumbOptions, _default as Breadcrumbs };
|
||||
196
dist/index.js
vendored
Normal file
196
dist/index.js
vendored
Normal file
|
|
@ -0,0 +1,196 @@
|
|||
import { simplifySlug as simplifySlug$1, joinSegments } from '@quartz-community/utils';
|
||||
import { jsx, jsxs } from 'preact/jsx-runtime';
|
||||
|
||||
// src/util/lang.ts
|
||||
function classNames(...classes) {
|
||||
return classes.filter(Boolean).join(" ");
|
||||
}
|
||||
function simplifySlug(fp) {
|
||||
return simplifySlug$1(fp);
|
||||
}
|
||||
function resolveRelative(current, target) {
|
||||
const simplified = simplifySlug(target);
|
||||
const rootPath = pathToRoot(current);
|
||||
return joinSegments(rootPath, simplified);
|
||||
}
|
||||
function pathToRoot(slug) {
|
||||
let rootPath = slug.split("/").filter((x) => x !== "").slice(0, -1).map((_) => "..").join("/");
|
||||
if (rootPath.length === 0) {
|
||||
rootPath = ".";
|
||||
}
|
||||
return rootPath;
|
||||
}
|
||||
var FileTrieNode = class _FileTrieNode {
|
||||
isFolder;
|
||||
children;
|
||||
slugSegments;
|
||||
fileSegmentHint;
|
||||
displayNameOverride;
|
||||
data;
|
||||
constructor(segments, data) {
|
||||
this.children = [];
|
||||
this.slugSegments = segments;
|
||||
this.data = data ?? null;
|
||||
this.isFolder = false;
|
||||
this.displayNameOverride = void 0;
|
||||
}
|
||||
get displayName() {
|
||||
const nonIndexTitle = this.data?.title === "index" ? void 0 : this.data?.title;
|
||||
return this.displayNameOverride ?? nonIndexTitle ?? this.fileSegmentHint ?? this.slugSegment ?? "";
|
||||
}
|
||||
set displayName(name) {
|
||||
this.displayNameOverride = name;
|
||||
}
|
||||
get slug() {
|
||||
const path = joinSegments(...this.slugSegments);
|
||||
if (this.isFolder) {
|
||||
return joinSegments(path, "index");
|
||||
}
|
||||
return path;
|
||||
}
|
||||
get slugSegment() {
|
||||
return this.slugSegments[this.slugSegments.length - 1] ?? "";
|
||||
}
|
||||
makeChild(path, file) {
|
||||
const nextSegment = path[0];
|
||||
if (!nextSegment) {
|
||||
throw new Error("path is empty");
|
||||
}
|
||||
const fullPath = [...this.slugSegments, nextSegment];
|
||||
const child = new _FileTrieNode(fullPath, file);
|
||||
this.children.push(child);
|
||||
return child;
|
||||
}
|
||||
insert(path, file) {
|
||||
if (path.length === 0) {
|
||||
throw new Error("path is empty");
|
||||
}
|
||||
this.isFolder = true;
|
||||
const segment = path[0];
|
||||
if (!segment) {
|
||||
throw new Error("path is empty");
|
||||
}
|
||||
if (path.length === 1) {
|
||||
if (segment === "index") {
|
||||
this.data ??= file;
|
||||
} else {
|
||||
this.makeChild(path, file);
|
||||
}
|
||||
} else if (path.length > 1) {
|
||||
const child = this.children.find((c) => c.slugSegment === segment) ?? this.makeChild(path, void 0);
|
||||
const fileParts = file.filePath.split("/");
|
||||
const hint = fileParts.at(-path.length);
|
||||
if (hint) {
|
||||
child.fileSegmentHint = hint;
|
||||
}
|
||||
child.insert(path.slice(1), file);
|
||||
}
|
||||
}
|
||||
add(file) {
|
||||
this.insert(file.slug.split("/"), file);
|
||||
}
|
||||
findNode(path) {
|
||||
if (path.length === 0 || path.length === 1 && path[0] === "index") {
|
||||
return this;
|
||||
}
|
||||
return this.children.find((c) => c.slugSegment === path[0])?.findNode(path.slice(1));
|
||||
}
|
||||
ancestryChain(path) {
|
||||
if (path.length === 0 || path.length === 1 && path[0] === "index") {
|
||||
return [this];
|
||||
}
|
||||
const child = this.children.find((c) => c.slugSegment === path[0]);
|
||||
if (!child) {
|
||||
return void 0;
|
||||
}
|
||||
const childPath = child.ancestryChain(path.slice(1));
|
||||
if (!childPath) {
|
||||
return void 0;
|
||||
}
|
||||
return [this, ...childPath];
|
||||
}
|
||||
filter(filterFn) {
|
||||
this.children = this.children.filter(filterFn);
|
||||
this.children.forEach((child) => child.filter(filterFn));
|
||||
}
|
||||
map(mapFn) {
|
||||
mapFn(this);
|
||||
this.children.forEach((child) => child.map(mapFn));
|
||||
}
|
||||
sort(sortFn) {
|
||||
this.children = this.children.sort(sortFn);
|
||||
this.children.forEach((e) => e.sort(sortFn));
|
||||
}
|
||||
};
|
||||
function trieFromAllFiles(allFiles) {
|
||||
const trie = new FileTrieNode([]);
|
||||
allFiles.forEach((file) => {
|
||||
if (file.frontmatter) {
|
||||
trie.add({
|
||||
slug: file.slug,
|
||||
title: file.frontmatter.title ?? "",
|
||||
filePath: file.filePath
|
||||
});
|
||||
}
|
||||
});
|
||||
return trie;
|
||||
}
|
||||
|
||||
// src/components/styles/breadcrumbs.scss
|
||||
var breadcrumbs_default = ".breadcrumb-container {\n margin: 0;\n margin-top: 0.75rem;\n padding: 0;\n display: flex;\n flex-direction: row;\n flex-wrap: wrap;\n gap: 0.5rem;\n}\n\n.breadcrumb-element p {\n margin: 0;\n margin-left: 0.5rem;\n padding: 0;\n line-height: normal;\n}\n.breadcrumb-element {\n display: flex;\n flex-direction: row;\n align-items: center;\n justify-content: center;\n}";
|
||||
var defaultOptions = {
|
||||
spacerSymbol: "\u276F",
|
||||
rootName: "Home",
|
||||
resolveFrontmatterTitle: true,
|
||||
showCurrentPage: true
|
||||
};
|
||||
function formatCrumb(displayName, baseSlug, currentSlug) {
|
||||
return {
|
||||
displayName: displayName.replaceAll("-", " "),
|
||||
path: resolveRelative(baseSlug, currentSlug)
|
||||
};
|
||||
}
|
||||
var Breadcrumbs_default = ((opts) => {
|
||||
const options = { ...defaultOptions, ...opts };
|
||||
const Breadcrumbs = ({
|
||||
fileData,
|
||||
allFiles,
|
||||
displayClass,
|
||||
ctx
|
||||
}) => {
|
||||
const typedCtx = ctx ?? {};
|
||||
typedCtx.trie ??= trieFromAllFiles(
|
||||
allFiles
|
||||
);
|
||||
const trie = typedCtx.trie;
|
||||
const slug = fileData.slug;
|
||||
const slugParts = slug.split("/");
|
||||
const pathNodes = trie.ancestryChain(slugParts);
|
||||
if (!pathNodes) {
|
||||
return null;
|
||||
}
|
||||
const crumbs = pathNodes.map((node, idx) => {
|
||||
const crumb = formatCrumb(node.displayName, slug, simplifySlug(node.slug));
|
||||
if (idx === 0) {
|
||||
crumb.displayName = options.rootName;
|
||||
}
|
||||
if (idx === pathNodes.length - 1) {
|
||||
crumb.path = "";
|
||||
}
|
||||
return crumb;
|
||||
});
|
||||
if (!options.showCurrentPage) {
|
||||
crumbs.pop();
|
||||
}
|
||||
return /* @__PURE__ */ jsx("nav", { class: classNames(displayClass, "breadcrumb-container"), "aria-label": "breadcrumbs", children: crumbs.map((crumb, index) => /* @__PURE__ */ jsxs("div", { class: "breadcrumb-element", children: [
|
||||
/* @__PURE__ */ jsx("a", { href: crumb.path, children: crumb.displayName }),
|
||||
index !== crumbs.length - 1 && /* @__PURE__ */ jsx("p", { children: ` ${options.spacerSymbol} ` })
|
||||
] })) });
|
||||
};
|
||||
Breadcrumbs.css = breadcrumbs_default;
|
||||
return Breadcrumbs;
|
||||
});
|
||||
|
||||
export { Breadcrumbs_default as Breadcrumbs };
|
||||
//# sourceMappingURL=index.js.map
|
||||
//# sourceMappingURL=index.js.map
|
||||
1
dist/index.js.map
vendored
Normal file
1
dist/index.js.map
vendored
Normal file
File diff suppressed because one or more lines are too long
7
package-lock.json
generated
7
package-lock.json
generated
|
|
@ -10,9 +10,7 @@
|
|||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@quartz-community/types": "github:quartz-community/types",
|
||||
"@quartz-community/utils": "github:quartz-community/utils",
|
||||
"tsup": "^8.5.0",
|
||||
"typescript": "^5.9.3"
|
||||
"@quartz-community/utils": "github:quartz-community/utils"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/hast": "^3.0.4",
|
||||
|
|
@ -26,6 +24,8 @@
|
|||
"prettier": "^3.6.2",
|
||||
"sass": "^1.97.3",
|
||||
"sass-embedded": "^1.79.5",
|
||||
"tsup": "^8.5.0",
|
||||
"typescript": "^5.9.3",
|
||||
"vfile": "^6.0.3",
|
||||
"vitest": "^2.1.9"
|
||||
},
|
||||
|
|
@ -4061,7 +4061,6 @@
|
|||
}
|
||||
],
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"nanoid": "^3.3.11",
|
||||
"picocolors": "^1.1.1",
|
||||
|
|
|
|||
|
|
@ -39,7 +39,6 @@
|
|||
"sideEffects": false,
|
||||
"scripts": {
|
||||
"build": "tsup",
|
||||
"prepare": "npm run build",
|
||||
"dev": "tsup --watch",
|
||||
"lint": "eslint . --max-warnings=0",
|
||||
"format": "prettier . --check",
|
||||
|
|
|
|||
Loading…
Reference in a new issue