vuepress-plugin-md-power 1.0.0-rc.144 → 1.0.0-rc.145

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,13 +1,12 @@
1
1
  <script setup lang="ts">
2
2
  import type { Ref } from 'vue'
3
- import { FadeInExpandTransition } from '@vuepress/helper/client'
4
3
  import { inject, ref } from 'vue'
5
4
 
6
- import '@vuepress/helper/transition/fade-in-height-expand.css'
7
-
8
5
  const props = defineProps<{
9
6
  type: 'file' | 'folder'
10
7
  filename: string
8
+ level: number
9
+ diff?: 'add' | 'remove'
11
10
  expanded?: boolean
12
11
  focus?: boolean
13
12
  }>()
@@ -49,18 +48,20 @@ function toggle(ev: MouseEvent) {
49
48
  focus,
50
49
  expanded: type === 'folder' ? active : false,
51
50
  active: type === 'file' ? activeFileTreeNode === filename : false,
51
+ diff,
52
+ add: diff === 'add',
53
+ remove: diff === 'remove',
52
54
  }"
55
+ :style="{ '--file-tree-level': -level }"
53
56
  @click="toggle"
54
57
  >
55
58
  <slot name="icon" />
56
59
  <span class="name" :class="[type]">{{ filename }}</span>
57
60
  <span v-if="$slots.comment" class="comment"><slot name="comment" /></span>
58
61
  </p>
59
- <FadeInExpandTransition>
60
- <div v-if="type === 'folder'" v-show="active" class="group">
61
- <slot />
62
- </div>
63
- </FadeInExpandTransition>
62
+ <div v-if="type === 'folder'" v-show="active" class="group">
63
+ <slot />
64
+ </div>
64
65
  </div>
65
66
  </template>
66
67
 
@@ -100,24 +101,40 @@ function toggle(ev: MouseEvent) {
100
101
 
101
102
  .vp-file-tree .vp-file-tree-info::after {
102
103
  position: absolute;
103
- top: 1px;
104
- right: 0;
105
- bottom: 1px;
106
- left: -16px;
104
+ top: 0;
105
+ right: -16px;
106
+ bottom: 0;
107
+ left: calc(var(--file-tree-level) * 28px - 32px);
107
108
  z-index: 0;
108
109
  display: block;
109
110
  pointer-events: none;
110
111
  content: "";
111
112
  background-color: transparent;
112
- border-radius: 6px;
113
113
  transition: background-color var(--vp-t-color);
114
114
  }
115
115
 
116
116
  .vp-file-tree .vp-file-tree-info.active::after,
117
- .vp-file-tree .vp-file-tree-info:hover::after {
117
+ .vp-file-tree .vp-file-tree-info:not(.diff):hover::after {
118
118
  background-color: var(--vp-c-default-soft);
119
119
  }
120
120
 
121
+ .vp-file-tree .vp-file-tree-info.diff::after {
122
+ padding-left: 4px;
123
+ font-size: 1.25em;
124
+ }
125
+
126
+ .vp-file-tree .vp-file-tree-info.diff.add::after {
127
+ color: var(--vp-c-success-1);
128
+ content: "+";
129
+ background-color: var(--vp-c-success-soft);
130
+ }
131
+
132
+ .vp-file-tree .vp-file-tree-info.diff.remove::after {
133
+ color: var(--vp-c-danger-1);
134
+ content: "-";
135
+ background-color: var(--vp-c-danger-soft);
136
+ }
137
+
121
138
  .vp-file-tree .vp-file-tree-info.folder {
122
139
  cursor: pointer;
123
140
  }
@@ -0,0 +1,94 @@
1
+ <script lang="ts" setup>
2
+ defineProps<{
3
+ name: string
4
+ type?: string
5
+ required?: boolean
6
+ optional?: boolean
7
+ defaultValue?: string
8
+ }>()
9
+ </script>
10
+
11
+ <template>
12
+ <div class="vp-field">
13
+ <p class="field-meta">
14
+ <span class="name">{{ name }}</span>
15
+ <span v-if="required || optional" :class="{ required, optional }">{{ required ? 'Required' : optional ? 'Optional' : '' }}</span>
16
+ <span v-if="type" class="type"><code>{{ type }}</code></span>
17
+ </p>
18
+ <p v-if="defaultValue" class="default-value">
19
+ <code>{{ defaultValue }}</code>
20
+ </p>
21
+ <div v-if="$slots.default" class="description">
22
+ <slot />
23
+ </div>
24
+ </div>
25
+ </template>
26
+
27
+ <style>
28
+ .vp-field {
29
+ width: 100%;
30
+ margin: 16px 0;
31
+ transition: border-color var(--vp-t-color);
32
+ }
33
+
34
+ .vp-field + .vp-field {
35
+ padding-top: 8px;
36
+ border-top: solid 1px var(--vp-c-divider);
37
+ }
38
+
39
+ .vp-field .field-meta {
40
+ display: flex;
41
+ gap: 8px;
42
+ align-items: flex-start;
43
+ margin: 8px 0;
44
+ }
45
+
46
+ .vp-field .field-meta .name {
47
+ font-size: 18px;
48
+ font-weight: 500;
49
+ }
50
+
51
+ .vp-field .field-meta .required,
52
+ .vp-field .field-meta .optional {
53
+ display: inline-block;
54
+ padding: 2px 8px;
55
+ font-size: 12px;
56
+ font-style: italic;
57
+ line-height: 1;
58
+ border-radius: 8px;
59
+ }
60
+
61
+ .vp-field .field-meta .required {
62
+ color: var(--vp-c-success-2);
63
+ border: solid 1px var(--vp-c-success-2);
64
+ }
65
+
66
+ .vp-field .field-meta .optional {
67
+ color: var(--vp-c-text-3);
68
+ border: solid 1px var(--vp-c-divider);
69
+ }
70
+
71
+ .vp-field .field-meta .type {
72
+ flex: 1 2;
73
+ text-align: right;
74
+ }
75
+
76
+ .vp-field .default-value {
77
+ margin: 0;
78
+ font-size: 14px;
79
+ line-height: 1;
80
+ }
81
+
82
+ .vp-field .description :where(p, ul, ol) {
83
+ margin: 8px 0;
84
+ line-height: 24px;
85
+ color: var(--vp-c-text-2);
86
+ }
87
+
88
+ .vp-field-group {
89
+ padding: 0 20px;
90
+ margin: 16px 0;
91
+ border: solid 1px var(--vp-c-divider);
92
+ border-radius: 6px;
93
+ }
94
+ </style>
@@ -268,6 +268,12 @@ interface MarkdownPowerPluginOptions {
268
268
  * @default false
269
269
  */
270
270
  chat?: boolean;
271
+ /**
272
+ * 是否启用 field / field-group 容器
273
+ *
274
+ * @default false
275
+ */
276
+ field?: boolean;
271
277
  /**
272
278
  * 是否启用 bilibili 视频嵌入
273
279
  *
package/lib/node/index.js CHANGED
@@ -1448,6 +1448,23 @@ function demoWrapperPlugin(md) {
1448
1448
  });
1449
1449
  }
1450
1450
 
1451
+ // src/node/container/field.ts
1452
+ import { isUndefined as isUndefined2 } from "@pengzhanbo/utils";
1453
+ function fieldPlugin(md) {
1454
+ createContainerPlugin(md, "field", {
1455
+ before: (info) => {
1456
+ const { attrs: attrs2 } = resolveAttrs(info);
1457
+ const { name, type, required, optional, default: defaultValue } = attrs2;
1458
+ const props = stringifyAttrs({ name, required, optional });
1459
+ return `<VPField${props}${!isUndefined2(type) ? ` type="${type}"` : ""}${!isUndefined2(defaultValue) ? ` default-value="${defaultValue}"` : ""}>`;
1460
+ },
1461
+ after: () => "</VPField>"
1462
+ });
1463
+ createContainerPlugin(md, "field-group", {
1464
+ before: () => '<div class="vp-field-group">'
1465
+ });
1466
+ }
1467
+
1451
1468
  // src/node/container/fileTree.ts
1452
1469
  import { removeEndingSlash } from "vuepress/shared";
1453
1470
  function parseFileTreeRawContent(content) {
@@ -1477,6 +1494,14 @@ function parseFileTreeNodeInfo(info) {
1477
1494
  let focus = false;
1478
1495
  let expanded = true;
1479
1496
  let type = "file";
1497
+ let diff;
1498
+ if (info.startsWith("++")) {
1499
+ info = info.slice(2).trim();
1500
+ diff = "add";
1501
+ } else if (info.startsWith("--")) {
1502
+ info = info.slice(2).trim();
1503
+ diff = "remove";
1504
+ }
1480
1505
  info = info.replace(RE_FOCUS, (_, matched) => {
1481
1506
  filename = matched;
1482
1507
  focus = true;
@@ -1493,7 +1518,7 @@ function parseFileTreeNodeInfo(info) {
1493
1518
  expanded = false;
1494
1519
  filename = removeEndingSlash(filename);
1495
1520
  }
1496
- return { filename, comment, focus, expanded, type };
1521
+ return { filename, comment, focus, expanded, type, diff };
1497
1522
  }
1498
1523
  function fileTreePlugin(md, options = {}) {
1499
1524
  const getIcon = (filename, type, mode) => {
@@ -1504,7 +1529,7 @@ function fileTreePlugin(md, options = {}) {
1504
1529
  };
1505
1530
  const renderFileTree = (nodes, meta) => nodes.map((node) => {
1506
1531
  const { info, level, children } = node;
1507
- const { filename, comment, focus, expanded, type } = parseFileTreeNodeInfo(info);
1532
+ const { filename, comment, focus, expanded, type, diff } = parseFileTreeNodeInfo(info);
1508
1533
  const isOmit = filename === "\u2026" || filename === "...";
1509
1534
  if (children.length === 0 && type === "folder") {
1510
1535
  children.push({ info: "\u2026", level: level + 1, children: [] });
@@ -1516,7 +1541,9 @@ function fileTreePlugin(md, options = {}) {
1516
1541
  expanded: nodeType === "folder" ? expanded : false,
1517
1542
  focus,
1518
1543
  type: nodeType,
1519
- filename
1544
+ diff,
1545
+ filename,
1546
+ level
1520
1547
  };
1521
1548
  return `<FileTreeNode${stringifyAttrs(props)}>
1522
1549
  ${renderedIcon}${renderedComment}${children.length > 0 ? renderFileTree(children, meta) : ""}
@@ -2095,6 +2122,8 @@ async function containerPlugin(app, md, options) {
2095
2122
  collapsePlugin(md);
2096
2123
  if (options.chat)
2097
2124
  chatPlugin(md);
2125
+ if (options.field)
2126
+ fieldPlugin(md);
2098
2127
  }
2099
2128
 
2100
2129
  // src/node/demo/demo.ts
@@ -3716,6 +3745,10 @@ async function prepareConfigFile(app, options) {
3716
3745
  if (options.chat) {
3717
3746
  imports.add(`import '${CLIENT_FOLDER}styles/chat.css'`);
3718
3747
  }
3748
+ if (options.field) {
3749
+ imports.add(`import VPField from '${CLIENT_FOLDER}components/VPField.vue'`);
3750
+ enhances.add(`app.component('VPField', VPField)`);
3751
+ }
3719
3752
  return app.writeTemp(
3720
3753
  "md-power/config.js",
3721
3754
  `import { defineClientConfig } from 'vuepress/client'
@@ -267,6 +267,12 @@ interface MarkdownPowerPluginOptions {
267
267
  * @default false
268
268
  */
269
269
  chat?: boolean;
270
+ /**
271
+ * 是否启用 field / field-group 容器
272
+ *
273
+ * @default false
274
+ */
275
+ field?: boolean;
270
276
  /**
271
277
  * 是否启用 bilibili 视频嵌入
272
278
  *
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "vuepress-plugin-md-power",
3
3
  "type": "module",
4
- "version": "1.0.0-rc.144",
4
+ "version": "1.0.0-rc.145",
5
5
  "description": "The Plugin for VuePress 2 - markdown power",
6
6
  "author": "pengzhanbo <volodymyr@foxmail.com>",
7
7
  "license": "MIT",
@@ -61,13 +61,13 @@
61
61
  }
62
62
  },
63
63
  "dependencies": {
64
- "@mdit/plugin-attrs": "^0.16.7",
65
- "@mdit/plugin-footnote": "^0.16.8",
66
- "@mdit/plugin-mark": "^0.16.0",
67
- "@mdit/plugin-sub": "^0.16.0",
68
- "@mdit/plugin-sup": "^0.16.0",
69
- "@mdit/plugin-tab": "^0.16.0",
70
- "@mdit/plugin-tasklist": "^0.16.0",
64
+ "@mdit/plugin-attrs": "^0.17.0",
65
+ "@mdit/plugin-footnote": "^0.17.0",
66
+ "@mdit/plugin-mark": "^0.17.0",
67
+ "@mdit/plugin-sub": "^0.17.0",
68
+ "@mdit/plugin-sup": "^0.17.0",
69
+ "@mdit/plugin-tab": "^0.17.0",
70
+ "@mdit/plugin-tasklist": "^0.17.0",
71
71
  "@pengzhanbo/utils": "^2.1.0",
72
72
  "@vuepress/helper": "2.0.0-rc.98",
73
73
  "@vueuse/core": "^13.1.0",