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) {
|
for (const transformer of plugins.transformers) {
|
||||||
const res = transformer.externalResources
|
const res = transformer.externalResources ? transformer.externalResources() : {}
|
||||||
if (res?.js) {
|
if (res?.js) {
|
||||||
staticResources.js = staticResources.js.concat(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 { visit } from "unist-util-visit"
|
||||||
import path from "path"
|
import path from "path"
|
||||||
import { JSResource } from "../../resources"
|
import { JSResource } from "../../resources"
|
||||||
|
// @ts-ignore
|
||||||
|
import calloutScript from "../../components/scripts/callout.inline.ts"
|
||||||
|
|
||||||
export interface Options {
|
export interface Options {
|
||||||
highlight: boolean
|
highlight: boolean
|
||||||
@ -210,6 +212,10 @@ export const ObsidianFlavoredMarkdown: QuartzTransformerPlugin<Partial<Options>
|
|||||||
const defaultState = collapseChar === "-" ? "collapsed" : "expanded"
|
const defaultState = collapseChar === "-" ? "collapsed" : "expanded"
|
||||||
const title = match.input.slice(calloutDirective.length).trim() || capitalize(calloutType)
|
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 = {
|
const titleNode: HTML = {
|
||||||
type: "html",
|
type: "html",
|
||||||
value: `<div
|
value: `<div
|
||||||
@ -217,6 +223,7 @@ export const ObsidianFlavoredMarkdown: QuartzTransformerPlugin<Partial<Options>
|
|||||||
>
|
>
|
||||||
<div class="callout-icon">${callouts[canonicalizeCallout(calloutType)]}</div>
|
<div class="callout-icon">${callouts[canonicalizeCallout(calloutType)]}</div>
|
||||||
<div class="callout-title-inner">${title}</div>
|
<div class="callout-title-inner">${title}</div>
|
||||||
|
${collapse ? toggleIcon : ""}
|
||||||
</div>`
|
</div>`
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -228,7 +235,6 @@ export const ObsidianFlavoredMarkdown: QuartzTransformerPlugin<Partial<Options>
|
|||||||
type: 'text',
|
type: 'text',
|
||||||
value: remainingText,
|
value: remainingText,
|
||||||
}]
|
}]
|
||||||
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -236,7 +242,6 @@ export const ObsidianFlavoredMarkdown: QuartzTransformerPlugin<Partial<Options>
|
|||||||
node.children.splice(0, 1, ...blockquoteContent)
|
node.children.splice(0, 1, ...blockquoteContent)
|
||||||
|
|
||||||
// add properties to base blockquote
|
// add properties to base blockquote
|
||||||
// TODO: add the js to actually support collapsing callout
|
|
||||||
node.data = {
|
node.data = {
|
||||||
hProperties: {
|
hProperties: {
|
||||||
...(node.data?.hProperties ?? {}),
|
...(node.data?.hProperties ?? {}),
|
||||||
@ -273,18 +278,31 @@ export const ObsidianFlavoredMarkdown: QuartzTransformerPlugin<Partial<Options>
|
|||||||
return [rehypeRaw]
|
return [rehypeRaw]
|
||||||
},
|
},
|
||||||
externalResources() {
|
externalResources() {
|
||||||
const mermaidScript: JSResource = {
|
const js: JSResource[] = []
|
||||||
script: `
|
|
||||||
|
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';
|
import mermaid from 'https://cdn.jsdelivr.net/npm/mermaid/dist/mermaid.esm.min.mjs';
|
||||||
mermaid.initialize({ startOnLoad: true });
|
mermaid.initialize({ startOnLoad: true });
|
||||||
`,
|
`,
|
||||||
loadTime: 'afterDOMReady',
|
loadTime: 'afterDOMReady',
|
||||||
moduleType: 'module',
|
moduleType: 'module',
|
||||||
contentType: 'inline'
|
contentType: 'inline'
|
||||||
}
|
})
|
||||||
return {
|
|
||||||
js: opts.mermaid ? [mermaidScript] : []
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
console.log(js)
|
||||||
|
|
||||||
|
return { js }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,8 @@
|
|||||||
background-color: var(--bg);
|
background-color: var(--bg);
|
||||||
border-radius: 5px;
|
border-radius: 5px;
|
||||||
padding: 0 1rem;
|
padding: 0 1rem;
|
||||||
|
overflow-y: hidden;
|
||||||
|
transition: max-height 0.3s ease;
|
||||||
|
|
||||||
&[data-callout="note"] {
|
&[data-callout="note"] {
|
||||||
--color: #448aff;
|
--color: #448aff;
|
||||||
@ -71,8 +73,20 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 5px;
|
gap: 5px;
|
||||||
margin: 1rem 0;
|
padding: 1rem 0;
|
||||||
|
margin-bottom: -1rem;
|
||||||
color: var(--color);
|
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 {
|
.callout-icon {
|
||||||
|
Loading…
Reference in New Issue
Block a user