Collapse
Fold and unfold blocks of code.
content.md
```js// !collapse(1:4)function lorem(ipsum, dolor = 1) {const sit = ipsum == null ? 0 : 1dolor = sit - amet(dolor)return sit ? consectetur(ipsum) : []}// !collapse(1:4) collapsedfunction ipsum(ipsum, dolor = 1) {const sit = ipsum == null ? 0 : 1dolor = sit - amet(dolor)return sit ? consectetur(ipsum) : []}```
const sit = ipsum == null ? 0 : 1dolor = sit - amet(dolor)return sit ? consectetur(ipsum) : []}}
Click on the function signature to collapse/expand the content of the function
Implementation
We use the Collapsible
component from shadcn/ui:
npx shadcn@latest add collapsible
For each !collapse
annotation we need to add two extra annotations, one for the trigger and one for the content.
code.tsx
import {Collapsible,CollapsibleContent,CollapsibleTrigger,} from "@/components/ui/collapsible"import { ChevronDownIcon } from "lucide-react"const collapse: AnnotationHandler = {name: "collapse",transform: (annotation: BlockAnnotation) => {const { fromLineNumber } = annotationreturn [annotation,{...annotation,fromLineNumber: fromLineNumber,toLineNumber: fromLineNumber,name: "CollapseTrigger",},{...annotation,fromLineNumber: fromLineNumber + 1,name: "CollapseContent",},]},Block: ({ annotation, children }) => {return (<Collapsible defaultOpen={annotation.query !== "collapsed"}>{children}</Collapsible>)},}const icon = (<ChevronDownIconclassName=""size={15}/>)const collapseTrigger: AnnotationHandler = {name: "CollapseTrigger",onlyIfAnnotated: true,AnnotatedLine: ({ annotation, ...props }) => (<CollapsibleTrigger className=""><InnerLine merge={props} data={{ icon }} /></CollapsibleTrigger>),Line: (props) => {const icon = props.data?.icon as React.ReactNodereturn (<div className=""><span className="">{icon}</span><div className=""><InnerLine merge={props} /></div></div>)},}const collapseContent: AnnotationHandler = {name: "CollapseContent",Block: CollapsibleContent,}
Then we can pass the collapse
, collapseTrigger
, and collapseContent
handlers to the Pre
component:
code.tsx
async function Code({ codeblock }: { codeblock: RawCode }) {const highlighted = await highlight(codeblock, "github-dark")return (<Precode={highlighted}handlers={[collapse, collapseTrigger, collapseContent]}/>)}