collapsible callout
This commit is contained in:
parent
5162c3c977
commit
23624105fb
24
quartz/components/scripts/callout.inline.ts
Normal file
24
quartz/components/scripts/callout.inline.ts
Normal file
@ -0,0 +1,24 @@
|
||||
function toggleCallout(this: HTMLElement) {
|
||||
const outerBlock = this.parentElement!
|
||||
this.classList.toggle(`is-collapsed`)
|
||||
const collapsed = this.classList.contains(`is-collapsed`)
|
||||
const height = collapsed ? this.scrollHeight : outerBlock.scrollHeight
|
||||
outerBlock.style.maxHeight = height + `px`
|
||||
}
|
||||
|
||||
function setupCallout(div: HTMLElement) {
|
||||
const collapsed = div.classList.contains(`is-collapsed`)
|
||||
const title = div.firstElementChild!
|
||||
const height = collapsed ? title.scrollHeight : div.scrollHeight
|
||||
div.style.maxHeight = height + `px`
|
||||
}
|
||||
|
||||
document.addEventListener(`nav`, () => {
|
||||
const collapsible = document.getElementsByClassName(`callout is-collapsible`) as HTMLCollectionOf<HTMLElement>
|
||||
for (const div of collapsible) {
|
||||
const title = div.firstElementChild
|
||||
setupCallout(div)
|
||||
title?.removeEventListener(`click`, toggleCallout)
|
||||
title?.addEventListener(`click`, toggleCallout)
|
||||
}
|
||||
})
|
@ -83,7 +83,7 @@ export function getStaticResourcesFromPlugins(plugins: PluginTypes) {
|
||||
}
|
||||
|
||||
for (const transformer of plugins.transformers) {
|
||||
const res = transformer.externalResources
|
||||
const res = transformer.externalResources ? transformer.externalResources() : {}
|
||||
if (res?.js) {
|
||||
staticResources.js = staticResources.js.concat(res.js)
|
||||
}
|
||||
|
@ -7,6 +7,8 @@ import rehypeRaw from "rehype-raw"
|
||||
import { visit } from "unist-util-visit"
|
||||
import path from "path"
|
||||
import { JSResource } from "../../resources"
|
||||
// @ts-ignore
|
||||
import calloutScript from "../../components/scripts/callout.inline.ts"
|
||||
|
||||
export interface Options {
|
||||
highlight: boolean
|
||||
@ -210,6 +212,10 @@ export const ObsidianFlavoredMarkdown: QuartzTransformerPlugin<Partial<Options>
|
||||
const defaultState = collapseChar === "-" ? "collapsed" : "expanded"
|
||||
const title = match.input.slice(calloutDirective.length).trim() || capitalize(calloutType)
|
||||
|
||||
const toggleIcon = `<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">
|
||||
<polyline points="6 9 12 15 18 9"></polyline>
|
||||
</svg>`
|
||||
|
||||
const titleNode: HTML = {
|
||||
type: "html",
|
||||
value: `<div
|
||||
@ -217,6 +223,7 @@ export const ObsidianFlavoredMarkdown: QuartzTransformerPlugin<Partial<Options>
|
||||
>
|
||||
<div class="callout-icon">${callouts[canonicalizeCallout(calloutType)]}</div>
|
||||
<div class="callout-title-inner">${title}</div>
|
||||
${collapse ? toggleIcon : ""}
|
||||
</div>`
|
||||
}
|
||||
|
||||
@ -228,7 +235,6 @@ export const ObsidianFlavoredMarkdown: QuartzTransformerPlugin<Partial<Options>
|
||||
type: 'text',
|
||||
value: remainingText,
|
||||
}]
|
||||
|
||||
})
|
||||
}
|
||||
|
||||
@ -236,7 +242,6 @@ export const ObsidianFlavoredMarkdown: QuartzTransformerPlugin<Partial<Options>
|
||||
node.children.splice(0, 1, ...blockquoteContent)
|
||||
|
||||
// add properties to base blockquote
|
||||
// TODO: add the js to actually support collapsing callout
|
||||
node.data = {
|
||||
hProperties: {
|
||||
...(node.data?.hProperties ?? {}),
|
||||
@ -273,18 +278,31 @@ export const ObsidianFlavoredMarkdown: QuartzTransformerPlugin<Partial<Options>
|
||||
return [rehypeRaw]
|
||||
},
|
||||
externalResources() {
|
||||
const mermaidScript: JSResource = {
|
||||
script: `
|
||||
const js: JSResource[] = []
|
||||
|
||||
if (opts.callouts) {
|
||||
js.push({
|
||||
script: calloutScript,
|
||||
loadTime: 'afterDOMReady',
|
||||
contentType: 'inline'
|
||||
})
|
||||
}
|
||||
|
||||
if (opts.mermaid) {
|
||||
js.push({
|
||||
script: `
|
||||
import mermaid from 'https://cdn.jsdelivr.net/npm/mermaid/dist/mermaid.esm.min.mjs';
|
||||
mermaid.initialize({ startOnLoad: true });
|
||||
`,
|
||||
loadTime: 'afterDOMReady',
|
||||
moduleType: 'module',
|
||||
contentType: 'inline'
|
||||
}
|
||||
return {
|
||||
js: opts.mermaid ? [mermaidScript] : []
|
||||
loadTime: 'afterDOMReady',
|
||||
moduleType: 'module',
|
||||
contentType: 'inline'
|
||||
})
|
||||
}
|
||||
|
||||
console.log(js)
|
||||
|
||||
return { js }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -5,6 +5,8 @@
|
||||
background-color: var(--bg);
|
||||
border-radius: 5px;
|
||||
padding: 0 1rem;
|
||||
overflow-y: hidden;
|
||||
transition: max-height 0.3s ease;
|
||||
|
||||
&[data-callout="note"] {
|
||||
--color: #448aff;
|
||||
@ -71,8 +73,20 @@
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 5px;
|
||||
margin: 1rem 0;
|
||||
padding: 1rem 0;
|
||||
margin-bottom: -1rem;
|
||||
color: var(--color);
|
||||
|
||||
& .fold {
|
||||
margin-left: 0.5rem;
|
||||
transition: transform 0.3s ease;
|
||||
opacity: 0.8;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
&.is-collapsed .fold {
|
||||
transform: rotateZ(-90deg)
|
||||
}
|
||||
}
|
||||
|
||||
.callout-icon {
|
||||
|
Loading…
Reference in New Issue
Block a user