收起
折叠和展开代码块。
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) : []}}
点击函数签名来收起/展开函数内容
Implementation
我们使用来自 shadcn/ui 的 Collapsible 组件:
npx shadcn@latest add collapsible
对于每个 !collapse 注释,我们需要添加两个额外的注释,一个用于触发器,一个用于内容。
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,}
然后我们可以将 collapse、collapseTrigger 和 collapseContent 处理器传递给 Pre 组件:
code.tsx
async function Code({ codeblock }: { codeblock: RawCode }) {const highlighted = await highlight(codeblock, "github-dark")return (<Precode={highlighted}handlers={[collapse, collapseTrigger, collapseContent]}/>)}