diff --git a/.gitignore b/.gitignore index 657842b..ef88793 100644 --- a/.gitignore +++ b/.gitignore @@ -4,7 +4,6 @@ node_modules/ .pnp.js # Build output -dist/ build/ *.tsbuildinfo diff --git a/dist/components/index.js b/dist/components/index.js new file mode 100644 index 0000000..846d2ec --- /dev/null +++ b/dist/components/index.js @@ -0,0 +1,164 @@ +import { jsxs, jsx } from 'preact/jsx-runtime'; + +// src/util/lang.ts +function classNames(...classes) { + return classes.filter(Boolean).join(" "); +} + +// src/i18n/locales/en-US.ts +var en_US_default = { + components: { + tableOfContents: { + title: "Table of Contents" + } + } +}; + +// src/i18n/index.ts +var locales = { + "en-US": en_US_default +}; +function i18n(locale) { + return locales[locale] || en_US_default; +} + +// src/components/styles/legacyToc.scss +var legacyToc_default = "details.toc summary {\n cursor: pointer;\n}\ndetails.toc summary::marker {\n color: var(--dark);\n}\ndetails.toc summary > * {\n padding-left: 0.25rem;\n display: inline-block;\n margin: 0;\n}\ndetails.toc ul {\n list-style: none;\n margin: 0.5rem 1.25rem;\n padding: 0;\n}\ndetails.toc .depth-1 {\n padding-left: calc(1rem * 1);\n}\ndetails.toc .depth-2 {\n padding-left: calc(1rem * 2);\n}\ndetails.toc .depth-3 {\n padding-left: calc(1rem * 3);\n}\ndetails.toc .depth-4 {\n padding-left: calc(1rem * 4);\n}\ndetails.toc .depth-5 {\n padding-left: calc(1rem * 5);\n}\ndetails.toc .depth-6 {\n padding-left: calc(1rem * 6);\n}"; + +// src/components/styles/toc.scss +var toc_default = ".toc {\n display: flex;\n flex-direction: column;\n overflow-y: hidden;\n min-height: 1.4rem;\n flex: 0 0.5 auto;\n}\n.toc:has(button.toc-header.collapsed) {\n flex: 0 1 1.4rem;\n}\n\nbutton.toc-header {\n background-color: transparent;\n border: none;\n text-align: left;\n cursor: pointer;\n padding: 0;\n color: var(--dark);\n display: flex;\n align-items: center;\n}\nbutton.toc-header h3 {\n font-size: 1rem;\n display: inline-block;\n margin: 0;\n}\nbutton.toc-header .fold {\n margin-left: 0.5rem;\n transition: transform 0.3s ease;\n opacity: 0.8;\n}\nbutton.toc-header.collapsed .fold {\n transform: rotateZ(-90deg);\n}\n\nul.toc-content.overflow {\n list-style: none;\n position: relative;\n margin: 0.5rem 0;\n padding: 0;\n max-height: calc(100% - 2rem);\n overscroll-behavior: contain;\n list-style: none;\n}\nul.toc-content.overflow > li > a {\n color: var(--dark);\n opacity: 0.35;\n transition: 0.5s ease opacity, 0.3s ease color;\n}\nul.toc-content.overflow > li > a.in-view {\n opacity: 0.75;\n}\nul.toc-content.overflow .depth-0 {\n padding-left: calc(1rem * 0);\n}\nul.toc-content.overflow .depth-1 {\n padding-left: calc(1rem * 1);\n}\nul.toc-content.overflow .depth-2 {\n padding-left: calc(1rem * 2);\n}\nul.toc-content.overflow .depth-3 {\n padding-left: calc(1rem * 3);\n}\nul.toc-content.overflow .depth-4 {\n padding-left: calc(1rem * 4);\n}\nul.toc-content.overflow .depth-5 {\n padding-left: calc(1rem * 5);\n}\nul.toc-content.overflow .depth-6 {\n padding-left: calc(1rem * 6);\n}"; + +// src/components/scripts/toc.inline.ts +var toc_inline_default = 'var i=new IntersectionObserver(t=>{for(let e of t){let n=e.target.id,o=document.querySelectorAll(`a[data-for="${n}"]`),s=e.rootBounds?.height;s&&o.length>0&&(e.boundingClientRect.yc.classList.add("in-view")):o.forEach(c=>c.classList.remove("in-view")))}});function r(){this.classList.toggle("collapsed"),this.setAttribute("aria-expanded",this.getAttribute("aria-expanded")==="true"?"false":"true");let t=this.nextElementSibling;t&&t.classList.toggle("collapsed")}function a(){let t=Array.from(document.getElementsByClassName("toc"));for(let e of t){let n=e.querySelector(".toc-header"),o=e.querySelector(".toc-content");if(!n||!o)return;n.addEventListener("click",r);let s=()=>n.removeEventListener("click",r);window.addCleanup&&window.addCleanup(s)}}function d(){a(),i.disconnect(),document.querySelectorAll("h1[id], h2[id], h3[id], h4[id], h5[id], h6[id]").forEach(e=>i.observe(e))}document.addEventListener("nav",d);document.addEventListener("render",d);\n'; +var OverflowList = ({ + children, + ...props +}) => { + return /* @__PURE__ */ jsxs("ul", { ...props, class: [props.class, "overflow"].filter(Boolean).join(" "), id: props.id, children: [ + children, + /* @__PURE__ */ jsx("li", { class: "overflow-end" }) + ] }); +}; +var numLists = 0; +var OverflowList_default = () => { + const id = `list-${numLists++}`; + return { + OverflowList: (props) => /* @__PURE__ */ jsx(OverflowList, { ...props, id }), + overflowListAfterDOMLoaded: ` +document.addEventListener("nav", (e) => { + const observer = new IntersectionObserver((entries) => { + for (const entry of entries) { + const parentUl = entry.target.parentElement + if (!parentUl) return + if (entry.isIntersecting) { + parentUl.classList.remove("gradient-active") + } else { + parentUl.classList.add("gradient-active") + } + } + }) + + const ul = document.getElementById("${id}") + if (!ul) return + + const end = ul.querySelector(".overflow-end") + if (!end) return + + observer.observe(end) + const cleanup = () => observer.disconnect() + if (window.addCleanup) { + window.addCleanup(cleanup) + } +}) +` + }; +}; + +// src/util/resources.ts +function concatenateResources(...resources) { + return resources.filter((resource) => resource !== void 0).flat(); +} +var defaultOptions = { + layout: "modern" +}; +var numTocs = 0; +var TableOfContents_default = ((opts) => { + const layout = opts?.layout ?? defaultOptions.layout; + const { OverflowList: OverflowList2, overflowListAfterDOMLoaded } = OverflowList_default(); + const TableOfContents = (props) => { + const { fileData, cfg } = props; + if (!fileData?.toc) { + return null; + } + const id = `toc-${numTocs++}`; + return /* @__PURE__ */ jsxs("div", { class: classNames("toc"), children: [ + /* @__PURE__ */ jsxs( + "button", + { + type: "button", + class: fileData.collapseToc ? "collapsed toc-header" : "toc-header", + "aria-controls": id, + "aria-expanded": !fileData.collapseToc, + children: [ + /* @__PURE__ */ jsx("h3", { children: i18n(cfg.locale).components.tableOfContents.title }), + /* @__PURE__ */ jsx( + "svg", + { + xmlns: "http://www.w3.org/2000/svg", + width: "24", + height: "24", + viewBox: "0 0 24 24", + fill: "none", + stroke: "currentColor", + "stroke-width": "2", + "stroke-linecap": "round", + "stroke-linejoin": "round", + class: "fold", + children: /* @__PURE__ */ jsx("polyline", { points: "6 9 12 15 18 9" }) + } + ) + ] + } + ), + /* @__PURE__ */ jsx( + OverflowList2, + { + id, + class: fileData.collapseToc ? "collapsed toc-content" : "toc-content", + children: fileData.toc.map((tocEntry) => { + const slug = String(tocEntry.slug); + const depth = String(tocEntry.depth); + const text = String(tocEntry.text); + return /* @__PURE__ */ jsx("li", { class: `depth-${depth}`, children: /* @__PURE__ */ jsx("a", { href: `#${slug}`, "data-for": slug, children: text }) }, slug); + }) + } + ) + ] }); + }; + TableOfContents.css = toc_default; + TableOfContents.afterDOMLoaded = concatenateResources( + toc_inline_default, + overflowListAfterDOMLoaded + ); + const LegacyTableOfContents = (props) => { + const { fileData, cfg } = props; + if (!fileData?.toc) { + return null; + } + return /* @__PURE__ */ jsxs("details", { class: "toc", open: !fileData.collapseToc, children: [ + /* @__PURE__ */ jsx("summary", { children: /* @__PURE__ */ jsx("h3", { children: i18n(cfg.locale).components.tableOfContents.title }) }), + /* @__PURE__ */ jsx("ul", { children: fileData.toc.map((tocEntry) => { + const slug = String(tocEntry.slug); + const depth = String(tocEntry.depth); + const text = String(tocEntry.text); + return /* @__PURE__ */ jsx("li", { class: `depth-${depth}`, children: /* @__PURE__ */ jsx("a", { href: `#${slug}`, "data-for": slug, children: text }) }, slug); + }) }) + ] }); + }; + LegacyTableOfContents.css = legacyToc_default; + return layout === "modern" ? TableOfContents : LegacyTableOfContents; +}); + +export { TableOfContents_default as TableOfContents }; +//# sourceMappingURL=index.js.map +//# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/dist/components/index.js.map b/dist/components/index.js.map new file mode 100644 index 0000000..0e68b4c --- /dev/null +++ b/dist/components/index.js.map @@ -0,0 +1 @@ +{"version":3,"sources":["../../src/util/lang.ts","../../src/i18n/locales/en-US.ts","../../src/i18n/index.ts","../../src/components/styles/legacyToc.scss","../../src/components/styles/toc.scss","../../src/components/scripts/toc.inline.ts","../../src/components/OverflowList.tsx","../../src/util/resources.ts","../../src/components/TableOfContents.tsx"],"names":["OverflowList","jsxs","jsx"],"mappings":"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","file":"index.js","sourcesContent":["export function classNames(...classes: (string | undefined | null | false)[]): string {\n return classes.filter(Boolean).join(\" \");\n}\n","export default {\n components: {\n tableOfContents: {\n title: \"Table of Contents\",\n },\n },\n};\n","import enUS from \"./locales/en-US\";\n\nconst locales: Record = {\n \"en-US\": enUS,\n};\n\nexport function i18n(locale: string) {\n return locales[locale] || enUS;\n}\n","details.toc summary {\n cursor: pointer;\n}\ndetails.toc summary::marker {\n color: var(--dark);\n}\ndetails.toc summary > * {\n padding-left: 0.25rem;\n display: inline-block;\n margin: 0;\n}\ndetails.toc ul {\n list-style: none;\n margin: 0.5rem 1.25rem;\n padding: 0;\n}\ndetails.toc .depth-1 {\n padding-left: calc(1rem * 1);\n}\ndetails.toc .depth-2 {\n padding-left: calc(1rem * 2);\n}\ndetails.toc .depth-3 {\n padding-left: calc(1rem * 3);\n}\ndetails.toc .depth-4 {\n padding-left: calc(1rem * 4);\n}\ndetails.toc .depth-5 {\n padding-left: calc(1rem * 5);\n}\ndetails.toc .depth-6 {\n padding-left: calc(1rem * 6);\n}",".toc {\n display: flex;\n flex-direction: column;\n overflow-y: hidden;\n min-height: 1.4rem;\n flex: 0 0.5 auto;\n}\n.toc:has(button.toc-header.collapsed) {\n flex: 0 1 1.4rem;\n}\n\nbutton.toc-header {\n background-color: transparent;\n border: none;\n text-align: left;\n cursor: pointer;\n padding: 0;\n color: var(--dark);\n display: flex;\n align-items: center;\n}\nbutton.toc-header h3 {\n font-size: 1rem;\n display: inline-block;\n margin: 0;\n}\nbutton.toc-header .fold {\n margin-left: 0.5rem;\n transition: transform 0.3s ease;\n opacity: 0.8;\n}\nbutton.toc-header.collapsed .fold {\n transform: rotateZ(-90deg);\n}\n\nul.toc-content.overflow {\n list-style: none;\n position: relative;\n margin: 0.5rem 0;\n padding: 0;\n max-height: calc(100% - 2rem);\n overscroll-behavior: contain;\n list-style: none;\n}\nul.toc-content.overflow > li > a {\n color: var(--dark);\n opacity: 0.35;\n transition: 0.5s ease opacity, 0.3s ease color;\n}\nul.toc-content.overflow > li > a.in-view {\n opacity: 0.75;\n}\nul.toc-content.overflow .depth-0 {\n padding-left: calc(1rem * 0);\n}\nul.toc-content.overflow .depth-1 {\n padding-left: calc(1rem * 1);\n}\nul.toc-content.overflow .depth-2 {\n padding-left: calc(1rem * 2);\n}\nul.toc-content.overflow .depth-3 {\n padding-left: calc(1rem * 3);\n}\nul.toc-content.overflow .depth-4 {\n padding-left: calc(1rem * 4);\n}\nul.toc-content.overflow .depth-5 {\n padding-left: calc(1rem * 5);\n}\nul.toc-content.overflow .depth-6 {\n padding-left: calc(1rem * 6);\n}","var i=new IntersectionObserver(t=>{for(let e of t){let n=e.target.id,o=document.querySelectorAll(`a[data-for=\"${n}\"]`),s=e.rootBounds?.height;s&&o.length>0&&(e.boundingClientRect.yc.classList.add(\"in-view\")):o.forEach(c=>c.classList.remove(\"in-view\")))}});function r(){this.classList.toggle(\"collapsed\"),this.setAttribute(\"aria-expanded\",this.getAttribute(\"aria-expanded\")===\"true\"?\"false\":\"true\");let t=this.nextElementSibling;t&&t.classList.toggle(\"collapsed\")}function a(){let t=Array.from(document.getElementsByClassName(\"toc\"));for(let e of t){let n=e.querySelector(\".toc-header\"),o=e.querySelector(\".toc-content\");if(!n||!o)return;n.addEventListener(\"click\",r);let s=()=>n.removeEventListener(\"click\",r);window.addCleanup&&window.addCleanup(s)}}function d(){a(),i.disconnect(),document.querySelectorAll(\"h1[id], h2[id], h3[id], h4[id], h5[id], h6[id]\").forEach(e=>i.observe(e))}document.addEventListener(\"nav\",d);document.addEventListener(\"render\",d);\n","import type { JSX } from \"preact\";\n\nconst OverflowList = ({\n children,\n ...props\n}: JSX.HTMLAttributes & { id: string }) => {\n return (\n
    \n {children}\n
  • \n
\n );\n};\n\nlet numLists = 0;\nexport default () => {\n const id = `list-${numLists++}`;\n\n return {\n OverflowList: (props: JSX.HTMLAttributes) => (\n \n ),\n overflowListAfterDOMLoaded: `\ndocument.addEventListener(\"nav\", (e) => {\n const observer = new IntersectionObserver((entries) => {\n for (const entry of entries) {\n const parentUl = entry.target.parentElement\n if (!parentUl) return\n if (entry.isIntersecting) {\n parentUl.classList.remove(\"gradient-active\")\n } else {\n parentUl.classList.add(\"gradient-active\")\n }\n }\n })\n\n const ul = document.getElementById(\"${id}\")\n if (!ul) return\n\n const end = ul.querySelector(\".overflow-end\")\n if (!end) return\n\n observer.observe(end)\n const cleanup = () => observer.disconnect()\n if (window.addCleanup) {\n window.addCleanup(cleanup)\n }\n})\n`,\n };\n};\n","export type StringResource = string | string[] | undefined;\n\nexport function concatenateResources(...resources: StringResource[]): StringResource {\n return resources\n .filter((resource): resource is string | string[] => resource !== undefined)\n .flat();\n}\n","import type {\n QuartzComponent,\n QuartzComponentProps,\n QuartzComponentConstructor,\n} from \"@quartz-community/types\";\nimport { classNames } from \"../util/lang\";\nimport { i18n } from \"../i18n\";\nimport legacyStyle from \"./styles/legacyToc.scss\";\nimport modernStyle from \"./styles/toc.scss\";\n// @ts-expect-error - inline script imported as string by esbuild loader\nimport script from \"./scripts/toc.inline.ts\";\nimport OverflowListFactory from \"./OverflowList\";\nimport { concatenateResources } from \"../util/resources\";\n\ninterface Options {\n layout: \"modern\" | \"legacy\";\n}\n\nconst defaultOptions: Options = {\n layout: \"modern\",\n};\n\nlet numTocs = 0;\nexport default ((opts?: Partial) => {\n const layout = opts?.layout ?? defaultOptions.layout;\n const { OverflowList, overflowListAfterDOMLoaded } = OverflowListFactory();\n const TableOfContents: QuartzComponent = (props: QuartzComponentProps) => {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const { fileData, cfg } = props as any;\n if (!fileData?.toc) {\n return null;\n }\n\n const id = `toc-${numTocs++}`;\n return (\n
\n \n

{i18n(cfg.locale).components.tableOfContents.title}

\n \n \n \n \n \n {fileData.toc.map((tocEntry: Record) => {\n const slug = String(tocEntry.slug);\n const depth = String(tocEntry.depth);\n const text = String(tocEntry.text);\n return (\n
  • \n \n {text}\n \n
  • \n );\n })}\n \n
    \n );\n };\n\n TableOfContents.css = modernStyle;\n TableOfContents.afterDOMLoaded = concatenateResources(\n script,\n overflowListAfterDOMLoaded,\n ) as string;\n\n const LegacyTableOfContents: QuartzComponent = (props: QuartzComponentProps) => {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const { fileData, cfg } = props as any;\n if (!fileData?.toc) {\n return null;\n }\n return (\n
    \n \n

    {i18n(cfg.locale).components.tableOfContents.title}

    \n
    \n
      \n {fileData.toc.map((tocEntry: Record) => {\n const slug = String(tocEntry.slug);\n const depth = String(tocEntry.depth);\n const text = String(tocEntry.text);\n return (\n
    • \n \n {text}\n \n
    • \n );\n })}\n
    \n
    \n );\n };\n LegacyTableOfContents.css = legacyStyle;\n\n return layout === \"modern\" ? TableOfContents : LegacyTableOfContents;\n}) satisfies QuartzComponentConstructor>;\n"]} \ No newline at end of file diff --git a/dist/index.js b/dist/index.js new file mode 100644 index 0000000..294f28b --- /dev/null +++ b/dist/index.js @@ -0,0 +1,213 @@ +import { jsxs, jsx } from 'preact/jsx-runtime'; +import { visit } from 'unist-util-visit'; +import { toString } from 'mdast-util-to-string'; +import Slugger from 'github-slugger'; + +// src/util/lang.ts +function classNames(...classes) { + return classes.filter(Boolean).join(" "); +} + +// src/i18n/locales/en-US.ts +var en_US_default = { + components: { + tableOfContents: { + title: "Table of Contents" + } + } +}; + +// src/i18n/index.ts +var locales = { + "en-US": en_US_default +}; +function i18n(locale) { + return locales[locale] || en_US_default; +} + +// src/components/styles/legacyToc.scss +var legacyToc_default = "details.toc summary {\n cursor: pointer;\n}\ndetails.toc summary::marker {\n color: var(--dark);\n}\ndetails.toc summary > * {\n padding-left: 0.25rem;\n display: inline-block;\n margin: 0;\n}\ndetails.toc ul {\n list-style: none;\n margin: 0.5rem 1.25rem;\n padding: 0;\n}\ndetails.toc .depth-1 {\n padding-left: calc(1rem * 1);\n}\ndetails.toc .depth-2 {\n padding-left: calc(1rem * 2);\n}\ndetails.toc .depth-3 {\n padding-left: calc(1rem * 3);\n}\ndetails.toc .depth-4 {\n padding-left: calc(1rem * 4);\n}\ndetails.toc .depth-5 {\n padding-left: calc(1rem * 5);\n}\ndetails.toc .depth-6 {\n padding-left: calc(1rem * 6);\n}"; + +// src/components/styles/toc.scss +var toc_default = ".toc {\n display: flex;\n flex-direction: column;\n overflow-y: hidden;\n min-height: 1.4rem;\n flex: 0 0.5 auto;\n}\n.toc:has(button.toc-header.collapsed) {\n flex: 0 1 1.4rem;\n}\n\nbutton.toc-header {\n background-color: transparent;\n border: none;\n text-align: left;\n cursor: pointer;\n padding: 0;\n color: var(--dark);\n display: flex;\n align-items: center;\n}\nbutton.toc-header h3 {\n font-size: 1rem;\n display: inline-block;\n margin: 0;\n}\nbutton.toc-header .fold {\n margin-left: 0.5rem;\n transition: transform 0.3s ease;\n opacity: 0.8;\n}\nbutton.toc-header.collapsed .fold {\n transform: rotateZ(-90deg);\n}\n\nul.toc-content.overflow {\n list-style: none;\n position: relative;\n margin: 0.5rem 0;\n padding: 0;\n max-height: calc(100% - 2rem);\n overscroll-behavior: contain;\n list-style: none;\n}\nul.toc-content.overflow > li > a {\n color: var(--dark);\n opacity: 0.35;\n transition: 0.5s ease opacity, 0.3s ease color;\n}\nul.toc-content.overflow > li > a.in-view {\n opacity: 0.75;\n}\nul.toc-content.overflow .depth-0 {\n padding-left: calc(1rem * 0);\n}\nul.toc-content.overflow .depth-1 {\n padding-left: calc(1rem * 1);\n}\nul.toc-content.overflow .depth-2 {\n padding-left: calc(1rem * 2);\n}\nul.toc-content.overflow .depth-3 {\n padding-left: calc(1rem * 3);\n}\nul.toc-content.overflow .depth-4 {\n padding-left: calc(1rem * 4);\n}\nul.toc-content.overflow .depth-5 {\n padding-left: calc(1rem * 5);\n}\nul.toc-content.overflow .depth-6 {\n padding-left: calc(1rem * 6);\n}"; + +// src/components/scripts/toc.inline.ts +var toc_inline_default = 'var i=new IntersectionObserver(t=>{for(let e of t){let n=e.target.id,o=document.querySelectorAll(`a[data-for="${n}"]`),s=e.rootBounds?.height;s&&o.length>0&&(e.boundingClientRect.yc.classList.add("in-view")):o.forEach(c=>c.classList.remove("in-view")))}});function r(){this.classList.toggle("collapsed"),this.setAttribute("aria-expanded",this.getAttribute("aria-expanded")==="true"?"false":"true");let t=this.nextElementSibling;t&&t.classList.toggle("collapsed")}function a(){let t=Array.from(document.getElementsByClassName("toc"));for(let e of t){let n=e.querySelector(".toc-header"),o=e.querySelector(".toc-content");if(!n||!o)return;n.addEventListener("click",r);let s=()=>n.removeEventListener("click",r);window.addCleanup&&window.addCleanup(s)}}function d(){a(),i.disconnect(),document.querySelectorAll("h1[id], h2[id], h3[id], h4[id], h5[id], h6[id]").forEach(e=>i.observe(e))}document.addEventListener("nav",d);document.addEventListener("render",d);\n'; +var OverflowList = ({ + children, + ...props +}) => { + return /* @__PURE__ */ jsxs("ul", { ...props, class: [props.class, "overflow"].filter(Boolean).join(" "), id: props.id, children: [ + children, + /* @__PURE__ */ jsx("li", { class: "overflow-end" }) + ] }); +}; +var numLists = 0; +var OverflowList_default = () => { + const id = `list-${numLists++}`; + return { + OverflowList: (props) => /* @__PURE__ */ jsx(OverflowList, { ...props, id }), + overflowListAfterDOMLoaded: ` +document.addEventListener("nav", (e) => { + const observer = new IntersectionObserver((entries) => { + for (const entry of entries) { + const parentUl = entry.target.parentElement + if (!parentUl) return + if (entry.isIntersecting) { + parentUl.classList.remove("gradient-active") + } else { + parentUl.classList.add("gradient-active") + } + } + }) + + const ul = document.getElementById("${id}") + if (!ul) return + + const end = ul.querySelector(".overflow-end") + if (!end) return + + observer.observe(end) + const cleanup = () => observer.disconnect() + if (window.addCleanup) { + window.addCleanup(cleanup) + } +}) +` + }; +}; + +// src/util/resources.ts +function concatenateResources(...resources) { + return resources.filter((resource) => resource !== void 0).flat(); +} +var defaultOptions = { + layout: "modern" +}; +var numTocs = 0; +var TableOfContents_default = ((opts) => { + const layout = opts?.layout ?? defaultOptions.layout; + const { OverflowList: OverflowList2, overflowListAfterDOMLoaded } = OverflowList_default(); + const TableOfContents = (props) => { + const { fileData, cfg } = props; + if (!fileData?.toc) { + return null; + } + const id = `toc-${numTocs++}`; + return /* @__PURE__ */ jsxs("div", { class: classNames("toc"), children: [ + /* @__PURE__ */ jsxs( + "button", + { + type: "button", + class: fileData.collapseToc ? "collapsed toc-header" : "toc-header", + "aria-controls": id, + "aria-expanded": !fileData.collapseToc, + children: [ + /* @__PURE__ */ jsx("h3", { children: i18n(cfg.locale).components.tableOfContents.title }), + /* @__PURE__ */ jsx( + "svg", + { + xmlns: "http://www.w3.org/2000/svg", + width: "24", + height: "24", + viewBox: "0 0 24 24", + fill: "none", + stroke: "currentColor", + "stroke-width": "2", + "stroke-linecap": "round", + "stroke-linejoin": "round", + class: "fold", + children: /* @__PURE__ */ jsx("polyline", { points: "6 9 12 15 18 9" }) + } + ) + ] + } + ), + /* @__PURE__ */ jsx( + OverflowList2, + { + id, + class: fileData.collapseToc ? "collapsed toc-content" : "toc-content", + children: fileData.toc.map((tocEntry) => { + const slug = String(tocEntry.slug); + const depth = String(tocEntry.depth); + const text = String(tocEntry.text); + return /* @__PURE__ */ jsx("li", { class: `depth-${depth}`, children: /* @__PURE__ */ jsx("a", { href: `#${slug}`, "data-for": slug, children: text }) }, slug); + }) + } + ) + ] }); + }; + TableOfContents.css = toc_default; + TableOfContents.afterDOMLoaded = concatenateResources( + toc_inline_default, + overflowListAfterDOMLoaded + ); + const LegacyTableOfContents = (props) => { + const { fileData, cfg } = props; + if (!fileData?.toc) { + return null; + } + return /* @__PURE__ */ jsxs("details", { class: "toc", open: !fileData.collapseToc, children: [ + /* @__PURE__ */ jsx("summary", { children: /* @__PURE__ */ jsx("h3", { children: i18n(cfg.locale).components.tableOfContents.title }) }), + /* @__PURE__ */ jsx("ul", { children: fileData.toc.map((tocEntry) => { + const slug = String(tocEntry.slug); + const depth = String(tocEntry.depth); + const text = String(tocEntry.text); + return /* @__PURE__ */ jsx("li", { class: `depth-${depth}`, children: /* @__PURE__ */ jsx("a", { href: `#${slug}`, "data-for": slug, children: text }) }, slug); + }) }) + ] }); + }; + LegacyTableOfContents.css = legacyToc_default; + return layout === "modern" ? TableOfContents : LegacyTableOfContents; +}); +var defaultOptions2 = { + maxDepth: 3, + minEntries: 1, + showByDefault: true, + collapseByDefault: false +}; +var slugAnchor = new Slugger(); +var TableOfContentsTransformer = (userOpts) => { + const opts = { ...defaultOptions2, ...userOpts }; + return { + name: "TableOfContents", + markdownPlugins() { + return [ + () => { + return async (tree, file) => { + const frontmatter = file.data.frontmatter; + const display = frontmatter?.enableToc ?? opts.showByDefault; + if (display) { + slugAnchor.reset(); + const toc = []; + let highestDepth = opts.maxDepth; + visit(tree, "heading", (node) => { + if (node.depth <= opts.maxDepth) { + const text = toString(node); + highestDepth = Math.min(highestDepth, node.depth); + toc.push({ + depth: node.depth, + text, + slug: slugAnchor.slug(text) + }); + } + }); + if (toc.length > 0 && toc.length > opts.minEntries) { + file.data.toc = toc.map((entry) => ({ + ...entry, + depth: entry.depth - highestDepth + })); + file.data.collapseToc = opts.collapseByDefault; + } + } + }; + } + ]; + } + }; +}; + +export { TableOfContents_default as TableOfContents, TableOfContentsTransformer }; +//# sourceMappingURL=index.js.map +//# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/dist/index.js.map b/dist/index.js.map new file mode 100644 index 0000000..0c35b44 --- /dev/null +++ b/dist/index.js.map @@ -0,0 +1 @@ +{"version":3,"sources":["../src/util/lang.ts","../src/i18n/locales/en-US.ts","../src/i18n/index.ts","../src/components/styles/legacyToc.scss","../src/components/styles/toc.scss","../src/components/scripts/toc.inline.ts","../src/components/OverflowList.tsx","../src/util/resources.ts","../src/components/TableOfContents.tsx","../src/transformer.ts"],"names":["OverflowList","jsxs","jsx","defaultOptions"],"mappings":"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","file":"index.js","sourcesContent":["export function classNames(...classes: (string | undefined | null | false)[]): string {\n return classes.filter(Boolean).join(\" \");\n}\n","export default {\n components: {\n tableOfContents: {\n title: \"Table of Contents\",\n },\n },\n};\n","import enUS from \"./locales/en-US\";\n\nconst locales: Record = {\n \"en-US\": enUS,\n};\n\nexport function i18n(locale: string) {\n return locales[locale] || enUS;\n}\n","details.toc summary {\n cursor: pointer;\n}\ndetails.toc summary::marker {\n color: var(--dark);\n}\ndetails.toc summary > * {\n padding-left: 0.25rem;\n display: inline-block;\n margin: 0;\n}\ndetails.toc ul {\n list-style: none;\n margin: 0.5rem 1.25rem;\n padding: 0;\n}\ndetails.toc .depth-1 {\n padding-left: calc(1rem * 1);\n}\ndetails.toc .depth-2 {\n padding-left: calc(1rem * 2);\n}\ndetails.toc .depth-3 {\n padding-left: calc(1rem * 3);\n}\ndetails.toc .depth-4 {\n padding-left: calc(1rem * 4);\n}\ndetails.toc .depth-5 {\n padding-left: calc(1rem * 5);\n}\ndetails.toc .depth-6 {\n padding-left: calc(1rem * 6);\n}",".toc {\n display: flex;\n flex-direction: column;\n overflow-y: hidden;\n min-height: 1.4rem;\n flex: 0 0.5 auto;\n}\n.toc:has(button.toc-header.collapsed) {\n flex: 0 1 1.4rem;\n}\n\nbutton.toc-header {\n background-color: transparent;\n border: none;\n text-align: left;\n cursor: pointer;\n padding: 0;\n color: var(--dark);\n display: flex;\n align-items: center;\n}\nbutton.toc-header h3 {\n font-size: 1rem;\n display: inline-block;\n margin: 0;\n}\nbutton.toc-header .fold {\n margin-left: 0.5rem;\n transition: transform 0.3s ease;\n opacity: 0.8;\n}\nbutton.toc-header.collapsed .fold {\n transform: rotateZ(-90deg);\n}\n\nul.toc-content.overflow {\n list-style: none;\n position: relative;\n margin: 0.5rem 0;\n padding: 0;\n max-height: calc(100% - 2rem);\n overscroll-behavior: contain;\n list-style: none;\n}\nul.toc-content.overflow > li > a {\n color: var(--dark);\n opacity: 0.35;\n transition: 0.5s ease opacity, 0.3s ease color;\n}\nul.toc-content.overflow > li > a.in-view {\n opacity: 0.75;\n}\nul.toc-content.overflow .depth-0 {\n padding-left: calc(1rem * 0);\n}\nul.toc-content.overflow .depth-1 {\n padding-left: calc(1rem * 1);\n}\nul.toc-content.overflow .depth-2 {\n padding-left: calc(1rem * 2);\n}\nul.toc-content.overflow .depth-3 {\n padding-left: calc(1rem * 3);\n}\nul.toc-content.overflow .depth-4 {\n padding-left: calc(1rem * 4);\n}\nul.toc-content.overflow .depth-5 {\n padding-left: calc(1rem * 5);\n}\nul.toc-content.overflow .depth-6 {\n padding-left: calc(1rem * 6);\n}","var i=new IntersectionObserver(t=>{for(let e of t){let n=e.target.id,o=document.querySelectorAll(`a[data-for=\"${n}\"]`),s=e.rootBounds?.height;s&&o.length>0&&(e.boundingClientRect.yc.classList.add(\"in-view\")):o.forEach(c=>c.classList.remove(\"in-view\")))}});function r(){this.classList.toggle(\"collapsed\"),this.setAttribute(\"aria-expanded\",this.getAttribute(\"aria-expanded\")===\"true\"?\"false\":\"true\");let t=this.nextElementSibling;t&&t.classList.toggle(\"collapsed\")}function a(){let t=Array.from(document.getElementsByClassName(\"toc\"));for(let e of t){let n=e.querySelector(\".toc-header\"),o=e.querySelector(\".toc-content\");if(!n||!o)return;n.addEventListener(\"click\",r);let s=()=>n.removeEventListener(\"click\",r);window.addCleanup&&window.addCleanup(s)}}function d(){a(),i.disconnect(),document.querySelectorAll(\"h1[id], h2[id], h3[id], h4[id], h5[id], h6[id]\").forEach(e=>i.observe(e))}document.addEventListener(\"nav\",d);document.addEventListener(\"render\",d);\n","import type { JSX } from \"preact\";\n\nconst OverflowList = ({\n children,\n ...props\n}: JSX.HTMLAttributes & { id: string }) => {\n return (\n
      \n {children}\n
    • \n
    \n );\n};\n\nlet numLists = 0;\nexport default () => {\n const id = `list-${numLists++}`;\n\n return {\n OverflowList: (props: JSX.HTMLAttributes) => (\n \n ),\n overflowListAfterDOMLoaded: `\ndocument.addEventListener(\"nav\", (e) => {\n const observer = new IntersectionObserver((entries) => {\n for (const entry of entries) {\n const parentUl = entry.target.parentElement\n if (!parentUl) return\n if (entry.isIntersecting) {\n parentUl.classList.remove(\"gradient-active\")\n } else {\n parentUl.classList.add(\"gradient-active\")\n }\n }\n })\n\n const ul = document.getElementById(\"${id}\")\n if (!ul) return\n\n const end = ul.querySelector(\".overflow-end\")\n if (!end) return\n\n observer.observe(end)\n const cleanup = () => observer.disconnect()\n if (window.addCleanup) {\n window.addCleanup(cleanup)\n }\n})\n`,\n };\n};\n","export type StringResource = string | string[] | undefined;\n\nexport function concatenateResources(...resources: StringResource[]): StringResource {\n return resources\n .filter((resource): resource is string | string[] => resource !== undefined)\n .flat();\n}\n","import type {\n QuartzComponent,\n QuartzComponentProps,\n QuartzComponentConstructor,\n} from \"@quartz-community/types\";\nimport { classNames } from \"../util/lang\";\nimport { i18n } from \"../i18n\";\nimport legacyStyle from \"./styles/legacyToc.scss\";\nimport modernStyle from \"./styles/toc.scss\";\n// @ts-expect-error - inline script imported as string by esbuild loader\nimport script from \"./scripts/toc.inline.ts\";\nimport OverflowListFactory from \"./OverflowList\";\nimport { concatenateResources } from \"../util/resources\";\n\ninterface Options {\n layout: \"modern\" | \"legacy\";\n}\n\nconst defaultOptions: Options = {\n layout: \"modern\",\n};\n\nlet numTocs = 0;\nexport default ((opts?: Partial) => {\n const layout = opts?.layout ?? defaultOptions.layout;\n const { OverflowList, overflowListAfterDOMLoaded } = OverflowListFactory();\n const TableOfContents: QuartzComponent = (props: QuartzComponentProps) => {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const { fileData, cfg } = props as any;\n if (!fileData?.toc) {\n return null;\n }\n\n const id = `toc-${numTocs++}`;\n return (\n
    \n \n

    {i18n(cfg.locale).components.tableOfContents.title}

    \n \n \n \n \n \n {fileData.toc.map((tocEntry: Record) => {\n const slug = String(tocEntry.slug);\n const depth = String(tocEntry.depth);\n const text = String(tocEntry.text);\n return (\n
  • \n \n {text}\n \n
  • \n );\n })}\n \n
    \n );\n };\n\n TableOfContents.css = modernStyle;\n TableOfContents.afterDOMLoaded = concatenateResources(\n script,\n overflowListAfterDOMLoaded,\n ) as string;\n\n const LegacyTableOfContents: QuartzComponent = (props: QuartzComponentProps) => {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const { fileData, cfg } = props as any;\n if (!fileData?.toc) {\n return null;\n }\n return (\n
    \n \n

    {i18n(cfg.locale).components.tableOfContents.title}

    \n
    \n
      \n {fileData.toc.map((tocEntry: Record) => {\n const slug = String(tocEntry.slug);\n const depth = String(tocEntry.depth);\n const text = String(tocEntry.text);\n return (\n
    • \n \n {text}\n \n
    • \n );\n })}\n
    \n
    \n );\n };\n LegacyTableOfContents.css = legacyStyle;\n\n return layout === \"modern\" ? TableOfContents : LegacyTableOfContents;\n}) satisfies QuartzComponentConstructor>;\n","import type { QuartzTransformerPlugin } from \"@quartz-community/types\";\nimport type { Root } from \"mdast\";\nimport type { VFile } from \"vfile\";\nimport { visit } from \"unist-util-visit\";\nimport { toString } from \"mdast-util-to-string\";\nimport Slugger from \"github-slugger\";\n\nexport interface TableOfContentsTransformerOptions {\n maxDepth: 1 | 2 | 3 | 4 | 5 | 6;\n minEntries: number;\n showByDefault: boolean;\n collapseByDefault: boolean;\n}\n\nconst defaultOptions: TableOfContentsTransformerOptions = {\n maxDepth: 3,\n minEntries: 1,\n showByDefault: true,\n collapseByDefault: false,\n};\n\nexport interface TocEntry {\n depth: number;\n text: string;\n slug: string; // this is just the anchor (#some-slug), not the canonical slug\n}\n\nconst slugAnchor = new Slugger();\nexport const TableOfContentsTransformer: QuartzTransformerPlugin<\n Partial\n> = (userOpts) => {\n const opts = { ...defaultOptions, ...userOpts };\n return {\n name: \"TableOfContents\",\n markdownPlugins() {\n return [\n () => {\n return async (tree: Root, file: VFile) => {\n const frontmatter = file.data.frontmatter as Record | undefined;\n const display = frontmatter?.enableToc ?? opts.showByDefault;\n if (display) {\n slugAnchor.reset();\n const toc: TocEntry[] = [];\n let highestDepth: number = opts.maxDepth;\n visit(tree, \"heading\", (node) => {\n if (node.depth <= opts.maxDepth) {\n const text = toString(node);\n highestDepth = Math.min(highestDepth, node.depth);\n toc.push({\n depth: node.depth,\n text,\n slug: slugAnchor.slug(text),\n });\n }\n });\n\n if (toc.length > 0 && toc.length > opts.minEntries) {\n file.data.toc = toc.map((entry) => ({\n ...entry,\n depth: entry.depth - highestDepth,\n }));\n file.data.collapseToc = opts.collapseByDefault;\n }\n }\n };\n },\n ];\n },\n };\n};\n\ndeclare module \"vfile\" {\n interface DataMap {\n toc: TocEntry[];\n collapseToc: boolean;\n }\n}\n"]} \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index c073b1c..9808042 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,12 +10,7 @@ "license": "MIT", "dependencies": { "@quartz-community/types": "github:quartz-community/types", - "github-slugger": "^2.0.0", - "mdast": "^3.0.0", - "mdast-util-to-string": "^4.0.0", - "tsup": "^8.5.0", - "typescript": "^5.9.3", - "unist-util-visit": "^5.0.0" + "mdast": "^3.0.0" }, "devDependencies": { "@types/mdast": "^4.0.4", @@ -27,6 +22,8 @@ "preact": "^10.28.2", "prettier": "^3.6.2", "sass": "^1.97.3", + "tsup": "^8.5.0", + "typescript": "^5.9.3", "vitest": "^2.1.9" }, "engines": { @@ -35,14 +32,26 @@ }, "peerDependencies": { "@jackyzha0/quartz": "^4.5.2", - "preact": "^10.0.0" + "github-slugger": "^2.0.0", + "mdast-util-to-string": "^4.0.0", + "preact": "^10.0.0", + "unist-util-visit": "^5.0.0" }, "peerDependenciesMeta": { "@jackyzha0/quartz": { "optional": true }, + "github-slugger": { + "optional": true + }, + "mdast-util-to-string": { + "optional": true + }, "preact": { "optional": false + }, + "unist-util-visit": { + "optional": true } } }, @@ -2545,12 +2554,6 @@ "node": "^8.16.0 || ^10.6.0 || >=11.0.0" } }, - "node_modules/github-slugger": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/github-slugger/-/github-slugger-2.0.0.tgz", - "integrity": "sha512-IaOQ9puYtjrkq7Y0Ygl9KDZnrf/aiUJYUpVf89y8kyaxbRG7Y1SrX/jaumrv81vc61+kiMempujsM3Yw7w5qcw==", - "license": "ISC" - }, "node_modules/glob": { "version": "7.2.3", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", @@ -2929,19 +2932,6 @@ "deprecated": "`mdast` was renamed to `remark`", "license": "MIT" }, - "node_modules/mdast-util-to-string": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-4.0.0.tgz", - "integrity": "sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==", - "license": "MIT", - "dependencies": { - "@types/mdast": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, "node_modules/merge2": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", @@ -3242,7 +3232,6 @@ } ], "license": "MIT", - "peer": true, "dependencies": { "nanoid": "^3.3.11", "picocolors": "^1.1.1", @@ -3951,19 +3940,6 @@ "url": "https://opencollective.com/unified" } }, - "node_modules/unist-util-is": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-6.0.1.tgz", - "integrity": "sha512-LsiILbtBETkDz8I9p1dQ0uyRUWuaQzd/cuEeS1hoRSyW5E5XGmTzlwY1OrNzzakGowI9Dr/I8HVaw4hTtnxy8g==", - "license": "MIT", - "dependencies": { - "@types/unist": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, "node_modules/unist-util-stringify-position": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-4.0.0.tgz", @@ -3977,35 +3953,6 @@ "url": "https://opencollective.com/unified" } }, - "node_modules/unist-util-visit": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-5.1.0.tgz", - "integrity": "sha512-m+vIdyeCOpdr/QeQCu2EzxX/ohgS8KbnPDgFni4dQsfSCtpz8UqDyY5GjRru8PDKuYn7Fq19j1CQ+nJSsGKOzg==", - "license": "MIT", - "dependencies": { - "@types/unist": "^3.0.0", - "unist-util-is": "^6.0.0", - "unist-util-visit-parents": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/unist-util-visit-parents": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-6.0.2.tgz", - "integrity": "sha512-goh1s1TBrqSqukSc8wrjwWhL0hiJxgA8m4kFxGlQ+8FYQ3C/m11FcTs4YYem7V664AhHVvgoQLk890Ssdsr2IQ==", - "license": "MIT", - "dependencies": { - "@types/unist": "^3.0.0", - "unist-util-is": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, "node_modules/uri-js": { "version": "4.4.1", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", diff --git a/package.json b/package.json index ceaadd3..4bca95c 100644 --- a/package.json +++ b/package.json @@ -39,7 +39,6 @@ "sideEffects": false, "scripts": { "build": "tsup", - "prepare": "npm run build", "dev": "tsup --watch", "lint": "eslint . --max-warnings=0", "format": "prettier . --check",