This commit is contained in:
parent
16c768f3a9
commit
56c5eb5257
@ -42,6 +42,7 @@ export const themeGuide = defineNoteConfig({
|
||||
'card',
|
||||
'steps',
|
||||
'file-tree',
|
||||
'field',
|
||||
'tabs',
|
||||
'timeline',
|
||||
'demo-wrapper',
|
||||
|
||||
@ -31,6 +31,7 @@ export const theme: Theme = plumeTheme({
|
||||
timeline: true,
|
||||
collapse: true,
|
||||
chat: true,
|
||||
field: true,
|
||||
imageSize: 'all',
|
||||
pdf: true,
|
||||
caniuse: true,
|
||||
|
||||
@ -155,6 +155,12 @@ export default defineUserConfig({
|
||||
- **默认值**: `true`
|
||||
- **详情**: 是否启用文件树容器语法
|
||||
|
||||
### field
|
||||
|
||||
- **类型**: `boolean`
|
||||
- **默认值**: `false`
|
||||
- **详情**: 是否启用字段容器
|
||||
|
||||
### timeline
|
||||
|
||||
- **类型**: `boolean`
|
||||
|
||||
131
docs/notes/theme/guide/markdown/field.md
Normal file
131
docs/notes/theme/guide/markdown/field.md
Normal file
@ -0,0 +1,131 @@
|
||||
---
|
||||
title: 字段容器
|
||||
icon: solar:text-field-linear
|
||||
createTime: 2025/04/29 09:55:17
|
||||
permalink: /guide/markdown/field/
|
||||
badge: 新
|
||||
---
|
||||
|
||||
## 概述
|
||||
|
||||
在 markdown 中,使用 `::: field` 容器,用于描述字段信息,包括字段名称、字段类型、是否必填、默认值、详情等信息。
|
||||
|
||||
它适用于 描述配置中的字段、组件的 Props 等场景。
|
||||
|
||||
还可以使用额外的 `:::: field-group` 容器,用于组合多个 `::: field`。
|
||||
|
||||
## 启用
|
||||
|
||||
该功能默认不启用,您需要在 `theme` 配置中启用它。
|
||||
|
||||
```ts title=".vuepress/config.ts"
|
||||
export default defineUserConfig({
|
||||
theme: plumeTheme({
|
||||
markdown: {
|
||||
field: true, // [!code ++]
|
||||
},
|
||||
})
|
||||
})
|
||||
```
|
||||
|
||||
## 语法
|
||||
|
||||
```md
|
||||
<!-- 单个字段 -->
|
||||
::: field name="字段名" type="类型" required default="默认值"
|
||||
字段描述信息
|
||||
:::
|
||||
|
||||
<!-- 字段组合 -->
|
||||
:::: field-group
|
||||
|
||||
::: field name="字段名" type="类型" required default="默认值"
|
||||
字段描述信息
|
||||
:::
|
||||
|
||||
::: field name="字段名" type="类型" required default="默认值"
|
||||
字段描述信息
|
||||
:::
|
||||
|
||||
::::
|
||||
```
|
||||
|
||||
## 属性
|
||||
|
||||
::: field name="name" required type="string"
|
||||
字段名称
|
||||
:::
|
||||
|
||||
::: field name="type" type="string" optional
|
||||
字段类型
|
||||
:::
|
||||
|
||||
::: field name="required" type="boolean" optional
|
||||
是否必填
|
||||
:::
|
||||
|
||||
::: field name="optional" type="boolean" optional
|
||||
是否可选
|
||||
:::
|
||||
|
||||
::: field name="default" type="string" optional
|
||||
默认值
|
||||
:::
|
||||
|
||||
## 示例
|
||||
|
||||
**输入:**
|
||||
|
||||
```md
|
||||
::: field name="theme" type="ThemeConfig" required default="{}"
|
||||
主题配置
|
||||
:::
|
||||
|
||||
::: field name="enabled" type="boolean" optional default="true"
|
||||
是否启用
|
||||
:::
|
||||
```
|
||||
|
||||
**输出:**
|
||||
|
||||
::: field name="theme" type="ThemeConfig" required default="{}"
|
||||
主题配置
|
||||
:::
|
||||
|
||||
::: field name="enabled" type="boolean" optional default="true"
|
||||
是否启用
|
||||
:::
|
||||
|
||||
**输入:**
|
||||
|
||||
```md
|
||||
:::: field-group
|
||||
::: field name="theme" type="ThemeConfig" required default="{ base: '/' }"
|
||||
主题配置
|
||||
:::
|
||||
|
||||
::: field name="enabled" type="boolean" optional default="true"
|
||||
是否启用
|
||||
:::
|
||||
|
||||
::: field name="callback" type="(...args: any[]) => void" optional default="() => {}"
|
||||
回调函数
|
||||
:::
|
||||
::::
|
||||
```
|
||||
|
||||
**输出:**
|
||||
|
||||
:::: field-group
|
||||
::: field name="theme" type="ThemeConfig" required default="{ base: '/' }"
|
||||
主题配置
|
||||
:::
|
||||
|
||||
::: field name="enabled" type="boolean" optional default="true"
|
||||
是否启用
|
||||
:::
|
||||
|
||||
::: field name="callback" type="(...args: any[]) => void" optional default="() => {}"
|
||||
回调函数
|
||||
:::
|
||||
::::
|
||||
92
plugins/plugin-md-power/src/client/components/VPField.vue
Normal file
92
plugins/plugin-md-power/src/client/components/VPField.vue
Normal file
@ -0,0 +1,92 @@
|
||||
<script lang="ts" setup>
|
||||
defineProps<{
|
||||
name: string
|
||||
type?: string
|
||||
required?: boolean
|
||||
optional?: boolean
|
||||
defaultValue?: string
|
||||
}>()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="vp-field">
|
||||
<p class="field-meta">
|
||||
<span class="name">{{ name }}</span>
|
||||
<span v-if="required || optional" :class="{ required, optional }">{{ required ? 'Required' : optional ? 'Optional' : '' }}</span>
|
||||
<span v-if="type" class="type"><code>{{ type }}</code></span>
|
||||
</p>
|
||||
<p v-if="defaultValue" class="default-value">
|
||||
<code>{{ defaultValue }}</code>
|
||||
</p>
|
||||
<div v-if="$slots.default" class="description">
|
||||
<slot />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style>
|
||||
.vp-field {
|
||||
width: 100%;
|
||||
margin: 16px 0;
|
||||
border-bottom: solid 1px var(--vp-c-divider);
|
||||
transition: border-color var(--vp-t-color);
|
||||
}
|
||||
|
||||
.vp-field:last-of-type {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.vp-field .field-meta {
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
align-items: flex-start;
|
||||
margin: 8px 0;
|
||||
}
|
||||
|
||||
.vp-field .field-meta .name {
|
||||
font-size: 20px;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.vp-field .field-meta .required,
|
||||
.vp-field .field-meta .optional {
|
||||
display: inline-block;
|
||||
padding: 2px 8px;
|
||||
font-size: 12px;
|
||||
font-style: italic;
|
||||
line-height: 1;
|
||||
border-radius: 8px;
|
||||
}
|
||||
|
||||
.vp-field .field-meta .required {
|
||||
color: var(--vp-c-success-2);
|
||||
border: solid 1px var(--vp-c-success-2);
|
||||
}
|
||||
|
||||
.vp-field .field-meta .optional {
|
||||
color: var(--vp-c-text-3);
|
||||
border: solid 1px var(--vp-c-divider);
|
||||
}
|
||||
|
||||
.vp-field .field-meta .type {
|
||||
flex: 1 2;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.vp-field .default-value {
|
||||
margin: 0;
|
||||
font-size: 14px;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
.vp-field .description :where(p, ul, ol) {
|
||||
color: var(--vp-c-text-2);
|
||||
}
|
||||
|
||||
.vp-field-group {
|
||||
padding: 0 20px;
|
||||
margin: 16px 0;
|
||||
border: solid 1px var(--vp-c-divider);
|
||||
border-radius: 6px;
|
||||
}
|
||||
</style>
|
||||
33
plugins/plugin-md-power/src/node/container/field.ts
Normal file
33
plugins/plugin-md-power/src/node/container/field.ts
Normal file
@ -0,0 +1,33 @@
|
||||
import type { Markdown } from 'vuepress/markdown'
|
||||
import { isUndefined } from '@pengzhanbo/utils'
|
||||
import { resolveAttrs } from '../utils/resolveAttrs.js'
|
||||
import { stringifyAttrs } from '../utils/stringifyAttrs.js'
|
||||
import { createContainerPlugin } from './createContainer.js'
|
||||
|
||||
interface FieldAttrs {
|
||||
name: string
|
||||
type?: string
|
||||
required?: boolean
|
||||
optional?: boolean
|
||||
default?: string
|
||||
}
|
||||
|
||||
export function fieldPlugin(md: Markdown) {
|
||||
createContainerPlugin(md, 'field', {
|
||||
before: (info) => {
|
||||
const { attrs } = resolveAttrs<FieldAttrs>(info)
|
||||
const { name, type, required, optional, default: defaultValue } = attrs
|
||||
const props = stringifyAttrs({ name, required, optional })
|
||||
return `<VPField${props}${
|
||||
!isUndefined(type) ? ` type="${type}"` : ''
|
||||
}${
|
||||
!isUndefined(defaultValue) ? ` default-value="${defaultValue}"` : ''
|
||||
}>`
|
||||
},
|
||||
after: () => '</VPField>',
|
||||
})
|
||||
|
||||
createContainerPlugin(md, 'field-group', {
|
||||
before: () => '<div class="vp-field-group">',
|
||||
})
|
||||
}
|
||||
@ -8,6 +8,7 @@ import { chatPlugin } from './chat.js'
|
||||
import { codeTabs } from './codeTabs.js'
|
||||
import { collapsePlugin } from './collapse.js'
|
||||
import { demoWrapperPlugin } from './demoWrapper.js'
|
||||
import { fieldPlugin } from './field.js'
|
||||
import { fileTreePlugin } from './fileTree.js'
|
||||
import { langReplPlugin } from './langRepl.js'
|
||||
import { npmToPlugins } from './npmTo.js'
|
||||
@ -58,4 +59,7 @@ export async function containerPlugin(
|
||||
|
||||
if (options.chat)
|
||||
chatPlugin(md)
|
||||
|
||||
if (options.field)
|
||||
fieldPlugin(md)
|
||||
}
|
||||
|
||||
@ -120,6 +120,11 @@ export async function prepareConfigFile(app: App, options: MarkdownPowerPluginOp
|
||||
imports.add(`import '${CLIENT_FOLDER}styles/chat.css'`)
|
||||
}
|
||||
|
||||
if (options.field) {
|
||||
imports.add(`import VPField from '${CLIENT_FOLDER}components/VPField.vue'`)
|
||||
enhances.add(`app.component('VPField', VPField)`)
|
||||
}
|
||||
|
||||
return app.writeTemp(
|
||||
'md-power/config.js',
|
||||
`\
|
||||
|
||||
@ -109,6 +109,12 @@ export interface MarkdownPowerPluginOptions {
|
||||
*/
|
||||
chat?: boolean
|
||||
|
||||
/**
|
||||
* 是否启用 field / field-group 容器
|
||||
*
|
||||
* @default false
|
||||
*/
|
||||
field?: boolean
|
||||
// video embed
|
||||
/**
|
||||
* 是否启用 bilibili 视频嵌入
|
||||
|
||||
@ -50,6 +50,7 @@ export const MARKDOWN_POWER_FIELDS: (keyof MarkdownPowerPluginOptions)[] = [
|
||||
'codepen',
|
||||
'demo',
|
||||
'fileTree',
|
||||
'field',
|
||||
'icons',
|
||||
'imageSize',
|
||||
'jsfiddle',
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user