| quartz/components/scripts/callout.inline.ts | ●●●●● patch | view | raw | blame | history | |
| quartz/plugins/transformers/ofm.ts | ●●●●● patch | view | raw | blame | history | |
| quartz/styles/callouts.scss | ●●●●● patch | view | raw | blame | history |
quartz/components/scripts/callout.inline.ts
@@ -1,25 +1,10 @@ function toggleCallout(this: HTMLElement) { const outerBlock = this.parentElement! outerBlock.classList.toggle("is-collapsed") const content = outerBlock.getElementsByClassName("callout-content")[0] as HTMLElement if (!content) return const collapsed = outerBlock.classList.contains("is-collapsed") const height = collapsed ? this.scrollHeight : outerBlock.scrollHeight outerBlock.style.maxHeight = height + "px" // walk and adjust height of all parents let current = outerBlock let parent = outerBlock.parentElement while (parent) { if (!parent.classList.contains("callout")) { return } const collapsed = parent.classList.contains("is-collapsed") const height = collapsed ? parent.scrollHeight : parent.scrollHeight + current.scrollHeight parent.style.maxHeight = height + "px" current = parent parent = parent.parentElement } content.style.gridTemplateRows = collapsed ? "0fr" : "1fr" } function setupCallout() { @@ -27,15 +12,15 @@ `callout is-collapsible`, ) as HTMLCollectionOf<HTMLElement> for (const div of collapsible) { const title = div.firstElementChild if (!title) continue const title = div.getElementsByClassName("callout-title")[0] as HTMLElement const content = div.getElementsByClassName("callout-content")[0] as HTMLElement if (!title || !content) continue title.addEventListener("click", toggleCallout) window.addCleanup(() => title.removeEventListener("click", toggleCallout)) const collapsed = div.classList.contains("is-collapsed") const height = collapsed ? title.scrollHeight : div.scrollHeight div.style.maxHeight = height + "px" content.style.gridTemplateRows = collapsed ? "0fr" : "1fr" } } quartz/plugins/transformers/ofm.ts
@@ -464,6 +464,30 @@ }) } // For the rest of the MD callout elements other than the title, wrap them with // two nested HTML <div>s (use some hacked mdhast component to achieve this) of // class `callout-content` and `callout-content-inner` respectively for // grid-based collapsible animation. if (calloutContent.length > 0) { node.children = [ node.children[0], { data: { hProperties: { className: ["callout-content"] }, hName: "div" }, type: "blockquote", children: [ { data: { hProperties: { className: ["callout-content-inner"] }, hName: "div", }, type: "blockquote", children: [...calloutContent], }, ], }, ] } // replace first line of blockquote with title and rest of the paragraph text node.children.splice(0, 1, ...blockquoteContent) @@ -485,21 +509,6 @@ "data-callout-metadata": calloutMetaData, }, } // Add callout-content class to callout body if it has one. if (calloutContent.length > 0) { const contentData: BlockContent | DefinitionContent = { data: { hProperties: { className: "callout-content", }, hName: "div", }, type: "blockquote", children: [...calloutContent], } node.children = [node.children[0], contentData] } } }) } quartz/styles/callouts.scss
@@ -7,11 +7,19 @@ border-radius: 5px; padding: 0 1rem; overflow-y: hidden; transition: max-height 0.3s ease; box-sizing: border-box; & > .callout-content > :first-child { margin-top: 0; & > .callout-content { display: grid; transition: grid-template-rows 0.3s ease; & > .callout-content-inner { overflow: hidden; & > :first-child { margin-top: 0; } } } --callout-icon-note: url('data:image/svg+xml; utf8, <svg xmlns="http://www.w3.org/2000/svg" width="100%" height="100%" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="18" y1="2" x2="22" y2="6"></line><path d="M7.5 20.5 19 9l-4-4L3.5 16.5 2 22z"></path></svg>');