An open API service indexing awesome lists of open source software.

https://github.com/hairyf/vitepress-plugin-demo

Markdown plugin for building demos in vitepress.
https://github.com/hairyf/vitepress-plugin-demo

demo markdown react vite vitepress vitepress-demo vitepress-plugin vue

Last synced: about 1 year ago
JSON representation

Markdown plugin for building demos in vitepress.

Awesome Lists containing this project

README

          

# vitepress-plugin-demo

[![npm version][npm-version-src]][npm-version-href]
[![npm downloads][npm-downloads-src]][npm-downloads-href]
[![bundle][bundle-src]][bundle-href]
[![JSDocs][jsdocs-src]][jsdocs-href]
[![License][license-src]][license-href]

## Features

- ✨ Use the `` or `container` in Markdown to reference a demo container.
- ♾️ Automatically convert TS code and provide JS demo code.
- πŸ‘½οΈ Support Vue, React, JS, TS and HTML demo block.
- πŸ“ Use Markdown syntax by you demo block description.
- πŸ’‘ Support [twoslash](https://shiki.style/packages/vitepress) syntax highlighting.
- πŸ“¦οΈ Supports multiple [presets](#presets), ready to use out of the box.
- 🎨 Customize the demo container to suit your needs.

***

`vitepress-plugin-demo` is a `markdown-it` plugin specifically designed for Vitepress demos. It converts code blocks in Markdown into references to the `` component. It does not generate UI itself but serves as a plugin for creating demo containers.

With this plugin, you can use the `` tag in Markdown to reference a demo container. For example:

```vue

```

You can use Markdown syntax in the `desc` field. For example:

```vue

```

However, we recommend using the `container` mode to write the `desc` content with Markdown:

```markdown
::: demo src="../demo.vue" title="Demo block"

This is a `description` that can be written using Markdown.

:::
```

This looks more aesthetically pleasing and adheres better to Markdown syntax.

In addition, you can pass the `attrs` parameter to `props`, so you can utilize the [Line Highlighting in Code Blocks](https://vitepress.dev/guide/markdown#line-highlighting-in-code-blocks) feature of VitePress:

```markdown

```

## Twoslash

`vitepress-plugin-demo` also supports [vitepress/twoslash](https://shiki.style/packages/vitepress) syntax highlighting. You can use the `twoslash` tag in Markdown to reference a demo container. For example:

```markdown

```

## React

`vitepress-plugin-demo` also supports React demo blocks. You can use the `react` tag in Markdown to reference a demo container.

```sh
npm install react react-dom --save-dev
```

import your React component:

```markdown

```

## Install

```bash
npm install vitepress-plugin-demo --save-dev
```

## Usage

```js
import { demoMdPlugin } from 'vitepress-plugin-demo'
// .vitepress/config.js
export default defineConfig({
markdown: {
config(md) {
md.use(demoMdPlugin)
},
},
})
```

Register your `` component in `theme/index.ts|js`:

```js
// https://vitepress.dev/guide/custom-theme
import Theme from 'vitepress/theme'

// your demo component
import CustomDemoContainer from './components/CustomDemoContainer.vue'

export default {
...Theme,
enhanceApp({ app, router, siteData }) {
app.component('demo-container', CustomDemoContainer)
},
}
```

## Presets

`vitepress-plugin-demo` pre-set common component library themes, which you can directly use:

Naive UI

```sh
npm install vitepress-plugin-demo naive-ui --save-dev
```

```js
import TwoslashFloating from '@shikijs/vitepress-twoslash/client'
import NaiveUIContainer from 'vitepress-plugin-demo/client/naive-ui'
import '@shikijs/vitepress-twoslash/style.css'

export default {
...Theme,
async enhanceApp({ app, router, siteData }) {
if (!import.meta.env.SSR) {
const { default: NaiveUI } = await import('naive-ui')
app.use(NaiveUI)
}
app.use(TwoslashFloating)
app.use(NaiveUIContainer, {
github: 'you github blob url',
codeeditor: {
editor: ['stackblitz', 'codesandbox'],
globals: {
package: {/* ... */},
files: {/* ... */},
opens: ['App.vue']
},
resolve(props) {
const code = props.typescript || props.javascript
return { /* cover global config */ }
}
},
})
},
}
```


## Customs

The `demo-container` component will receive relevant information about the demo, and you need to implement the rendering of the demo:

```vue

import { computed } from 'vue'

const props = defineProps<{
typescript: string
// if using ts, javascript will transform the to js
javascript: string
title: string
metadata: object
}>()

const code = computed(() => decodeURIComponent(props.typescript || props.javascript))


{{ title }}



Copy Code









```

Other `props` will not be processed and will be directly passed to the `` component. For example, you can customize whether the code is expanded using the `prop`:

```markdown

```

> however, it is important to note that `` is not strictly a component and cannot handle excessively complex custom `props`, such as `v-bind`.

```ts
const props = defineProps<{
// ...
expand: boolean
}>()
```

## Metadata

The `demo-container` component will receive relevant information about the demo. You can use the `metadata` to access and use this information within the demo:

```vue

const props = defineProps<{
typescript: string
javascript: string
title: string
// metadata returns information about the demo during build (absolutePath, relativePath, fileName)
metadata: object
}>()
const githubBlobUrl = 'https://www.github.com/.../tree/main/'
const githubPath = githubBlobUrl + props.metadata.relativePath

function toEditGithubDemoFile() {
window.open(githubPath)
}

```

## CodeSandbox

You can define the parameters for CodeSandbox by using `codesandbox/lib/api/define` and create a sandbox environment by submitting them to the CodeSandbox API through a ``:

```vue

import { getParameters } from 'codesandbox/lib/api/define'

const props = defineProps<{
typescript: string
javascript: string
// ...
}>()

// Compute the parameters for CodeSandbox
const parameters = computed(() => {
return getParameters({
files: {
'package.json': {
// specify your dependencies
content: { dependencies: { vue: 'latest' } },
},
'index.html': { content: `<div id="app"></div>` },
'App.vue': { content: decodeURIComponent(props.javascript) },
'src/main.js': { content: '...' },
},
})
})




Edit in CodeSandbox

```

## Development

```bash
pnpm install

# Run development server
pnpm dev

# Have fun!
pnpm play
```

> Unit tests are in progress, PRs welcome!

## Acknowledgements

This project draws inspiration from the following projects:

- [ruabick](https://github.com/dewfall123/ruabick)
- [vitepress-demo-preview](https://github.com/flingyp/vitepress-demo-preview)
- [create-vitepress-demo](https://github.com/bowencool/create-vitepress-demo)
- [naive-ui](https://github.com/tusen-ai/naive-ui)
- [element-plus](https://github.com/element-plus/element-plus)

## License

[MIT](./LICENSE) License Β© [Hairyf](https://github.com/hairyf)

[npm-version-src]: https://img.shields.io/npm/v/vitepress-plugin-demo?style=flat&colorA=080f12&colorB=1fa669
[npm-version-href]: https://npmjs.com/package/vitepress-plugin-demo
[npm-downloads-src]: https://img.shields.io/npm/dm/vitepress-plugin-demo?style=flat&colorA=080f12&colorB=1fa669
[npm-downloads-href]: https://npmjs.com/package/vitepress-plugin-demo
[bundle-src]: https://img.shields.io/bundlephobia/minzip/vitepress-plugin-demo?style=flat&colorA=080f12&colorB=1fa669&label=minzip
[bundle-href]: https://bundlephobia.com/result?p=vitepress-plugin-demo
[license-src]: https://img.shields.io/github/license/hairyf/vitepress-plugin-demo.svg?style=flat&colorA=080f12&colorB=1fa669
[license-href]: https://github.com/hairyf/vitepress-plugin-demo/blob/main/LICENSE
[jsdocs-src]: https://img.shields.io/badge/jsdocs-reference-080f12?style=flat&colorA=080f12&colorB=1fa669
[jsdocs-href]: https://www.jsdocs.io/package/vitepress-plugin-demo