shadcn-vue/apps/www/.vitepress/theme/plugins/utils.ts
zernonia 72f9bd5ef5
refactor: code preview (#411)
* feat: generate code dynamically

* chore: cleanup and transform path on component

* feat: create config sheet

* feat: code wrapper

* fix: not acting immediately

* chore: add key to vnode

* chore: add vue-sonner to demos dependencies, add placeholder for codeConfigs

* chore: fix wrong icons

* chore: improve crawling logic

---------

Co-authored-by: Sadegh Barati <sadeghbaratiwork@gmail.com>
2024-03-14 18:28:13 +08:00

41 lines
1.1 KiB
TypeScript

// Credit to @hairyf https://github.com/hairyf/markdown-it-vitepress-demo
import { baseParse } from '@vue/compiler-core'
import type { AttributeNode, ElementNode } from '@vue/compiler-core'
export interface GenerateOptions {
attrs?: string
props: Record<string, any>
path: string
code: string
}
export function isUndefined(v: any): v is undefined {
return v === undefined || v === null
}
function getPropsMap(attrs: any[]) {
const map: Record<string, any> = {}
for (const { name, value, exp, arg } of attrs) {
if (name === 'bind') {
if (!isUndefined(arg?.content))
map[arg.content] = JSON.parse(exp.content)
continue
}
if (isUndefined(value?.content) || value?.content === '')
map[name] = true
else if (['true', 'false'].includes(value?.content || ''))
map[name] = value?.content === 'true'
else
map[name] = value?.content
}
return map
}
export function parseProps(content: string) {
const ast = baseParse(content)
const demoElement = ast.children[0] as ElementNode
return getPropsMap(demoElement.props as AttributeNode[])
}