@do11y/docs 0.0.11 → 0.0.12

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.
package/dist/index.d.ts CHANGED
@@ -1,3 +1,7 @@
1
1
  import type { PluginOptions } from './plugin-options.js';
2
2
  import type { Site } from './plugins/site/site.js';
3
3
  export type { Site, PluginOptions };
4
+ export declare const vueOptions: {
5
+ include: RegExp[];
6
+ exclude: RegExp[];
7
+ };
package/dist/index.js CHANGED
@@ -1 +1,4 @@
1
- export {};
1
+ export const vueOptions = {
2
+ include: [/\.vue$/, /\.md$/],
3
+ exclude: [/\.vue\?meta$/],
4
+ };
@@ -1,5 +1,4 @@
1
1
  import { type MarkdownSfcBlocks } from '@mdit-vue/plugin-sfc';
2
- import type { PluginOptions, MarkdownItEnv as Env } from 'markdown-it-vue-meta';
3
2
  import type { PluginSimple } from 'markdown-it';
4
3
  import type { Plugin } from 'vite';
5
4
  import type MarkdownIt from 'markdown-it';
@@ -12,12 +11,8 @@ export interface MarkdownPluginOptions {
12
11
  * The highlight option for `markdown-it`.
13
12
  */
14
13
  highlight?: (md: MarkdownIt, code: string, lang: string, attrs: string) => string;
15
- /**
16
- * The renderer option for `markdown-it-vue-meta`.
17
- */
18
- metaRenderer?: PluginOptions['renderer'];
19
14
  }
20
- export interface MarkdownItEnv extends Env {
15
+ export interface MarkdownItEnv {
21
16
  /**
22
17
  * Blocks extracted by `@mdit-vue/plugin-sfc`.
23
18
  */
@@ -1,12 +1,8 @@
1
- import { join } from 'node:path';
2
- import { existsSync } from 'node:fs';
3
1
  import { componentPlugin } from '@mdit-vue/plugin-component';
4
2
  import { sfcPlugin } from '@mdit-vue/plugin-sfc';
5
3
  import { frontmatterPlugin } from '@mdit-vue/plugin-frontmatter';
6
4
  import attrsPlugin from 'markdown-it-attrs';
7
- import metaPlugin from 'markdown-it-vue-meta';
8
5
  import markdown from 'markdown-it';
9
- import { root } from '../../files.js';
10
6
  /**
11
7
  * Processes blocks with the lang set to `md` into HTML,
12
8
  * and turns `.md` files into single file vue components
@@ -23,16 +19,6 @@ export default (options) => {
23
19
  md.use(sfcPlugin);
24
20
  md.use(componentPlugin);
25
21
  md.use(attrsPlugin);
26
- if (options?.metaRenderer) {
27
- let tsconfig = join(root, 'tsconfig.app.json');
28
- if (!existsSync(tsconfig)) {
29
- tsconfig = join(root, 'tsconfig.json');
30
- }
31
- md.use(metaPlugin, {
32
- renderer: options.metaRenderer,
33
- tsconfig,
34
- });
35
- }
36
22
  if (options?.setup) {
37
23
  md.use(options.setup);
38
24
  }
@@ -41,9 +27,7 @@ export default (options) => {
41
27
  enforce: 'pre',
42
28
  transform(code, id) {
43
29
  if (id.endsWith('.md')) {
44
- const env = {
45
- path: id.replace(/[?#].*$/, ''),
46
- };
30
+ const env = {};
47
31
  const html = md.render(code, env);
48
32
  /**
49
33
  * If it's a markdown block, return the
@@ -0,0 +1,42 @@
1
+ import type { ComponentMeta } from 'vue-component-meta';
2
+ export declare const mapMeta: (meta: ComponentMeta, render: (input: string) => string) => {
3
+ modelValues: {
4
+ default: string | undefined;
5
+ required: boolean;
6
+ name: string;
7
+ type: string;
8
+ description: string;
9
+ deprecated: string | boolean;
10
+ tags: {
11
+ name: string;
12
+ text: string | undefined;
13
+ }[];
14
+ }[];
15
+ props: {
16
+ default: string | undefined;
17
+ required: boolean;
18
+ name: string;
19
+ type: string;
20
+ description: string;
21
+ deprecated: string | boolean;
22
+ tags: {
23
+ name: string;
24
+ text: string | undefined;
25
+ }[];
26
+ }[];
27
+ events: {
28
+ name: string;
29
+ type: string;
30
+ description: string;
31
+ deprecated: string | boolean;
32
+ tags: {
33
+ name: string;
34
+ text: string | undefined;
35
+ }[];
36
+ }[];
37
+ slots: {
38
+ name: string;
39
+ type: string;
40
+ description: string;
41
+ }[];
42
+ };
@@ -0,0 +1,50 @@
1
+ export const mapMeta = (meta, render) => {
2
+ const nonGlobalProps = meta.props.filter((prop) => !prop.global);
3
+ const hasAssociatedEvent = (prop) => {
4
+ return meta.events.some((event) => event.name === `update:${prop.name}`);
5
+ };
6
+ const hasAssociatedProp = (event) => {
7
+ return meta.props.some((prop) => `update:${prop.name}` === event.name);
8
+ };
9
+ const getDeprecated = (tags) => {
10
+ const deprecated = getTag(tags, 'deprecated');
11
+ return deprecated ? deprecated.text || true : false;
12
+ };
13
+ const getFilteredTags = (tags) => {
14
+ const filteredTags = tags.filter((t) => !['default', 'deprecated'].includes(t.name));
15
+ return filteredTags.map((tag) => ({
16
+ name: tag.name,
17
+ text: tag.text ? render(tag.text) : undefined,
18
+ }));
19
+ };
20
+ const mapPropertyAndEvent = (prop) => ({
21
+ name: prop.name,
22
+ type: prop.type,
23
+ description: render(prop.description),
24
+ deprecated: getDeprecated(prop.tags),
25
+ tags: getFilteredTags(prop.tags),
26
+ });
27
+ const mapSlotAndExposed = (m) => ({
28
+ name: m.name,
29
+ type: m.type,
30
+ description: render(m.description),
31
+ });
32
+ const mapProperty = (prop) => ({
33
+ ...mapPropertyAndEvent(prop),
34
+ default: prop.default || getTag(prop.tags, 'default')?.text,
35
+ required: prop.required,
36
+ });
37
+ return {
38
+ modelValues: nonGlobalProps
39
+ .filter((prop) => hasAssociatedEvent(prop))
40
+ .map((modelValue) => mapProperty(modelValue)),
41
+ props: nonGlobalProps
42
+ .filter((prop) => !hasAssociatedEvent(prop))
43
+ .map((prop) => mapProperty(prop)),
44
+ events: meta.events
45
+ .filter((event) => !hasAssociatedProp(event))
46
+ .map((event) => mapPropertyAndEvent(event)),
47
+ slots: meta.slots.map((slot) => mapSlotAndExposed(slot)),
48
+ };
49
+ };
50
+ const getTag = (tags, tag) => tags.find(({ name }) => name === tag);
@@ -0,0 +1,7 @@
1
+ import type { Plugin } from 'vite';
2
+ /**
3
+ * Adds `.vue?meta` imports which returns the results of
4
+ * running the component through `vue-component-meta`.
5
+ */
6
+ declare const _default: () => Plugin;
7
+ export default _default;
@@ -0,0 +1,35 @@
1
+ import { existsSync } from 'node:fs';
2
+ import { join } from 'node:path';
3
+ import { createChecker } from 'vue-component-meta';
4
+ import markdown from 'markdown-it';
5
+ import { root } from '../../files.js';
6
+ import { mapMeta } from './meta-mapper.js';
7
+ /**
8
+ * Adds `.vue?meta` imports which returns the results of
9
+ * running the component through `vue-component-meta`.
10
+ */
11
+ export default () => {
12
+ let tsconfig = join(root, 'tsconfig.app.json');
13
+ if (!existsSync(tsconfig)) {
14
+ tsconfig = join(root, 'tsconfig.json');
15
+ }
16
+ const checker = createChecker(tsconfig, {
17
+ noDeclarations: true,
18
+ });
19
+ const md = markdown();
20
+ return {
21
+ name: 'do11y:meta',
22
+ transform(_, id) {
23
+ if (id.endsWith('.vue?meta')) {
24
+ const file = id.replace('?meta', '');
25
+ const meta = checker.getComponentMeta(file);
26
+ const code = `export default ${JSON.stringify(mapMeta(meta, (content) => md.render(content)))}`;
27
+ return {
28
+ code,
29
+ map: { mappings: '' },
30
+ moduleType: 'js',
31
+ };
32
+ }
33
+ },
34
+ };
35
+ };
@@ -1,4 +1,5 @@
1
1
  import markdownPlugin from './markdown/markdown.js';
2
+ import metaPlugin from './meta/meta.js';
2
3
  import customBlockPlugin from 'v-custom-block';
3
4
  import sitePlugin from './site/site.js';
4
5
  import routesPlugin from './routes/routes.js';
@@ -8,6 +9,7 @@ import { pluginOptions } from '../plugin-options.js';
8
9
  export const plugins = () => [
9
10
  uiPlugin(),
10
11
  sandboxPlugin(),
12
+ metaPlugin(),
11
13
  markdownPlugin(pluginOptions),
12
14
  customBlockPlugin('docs'),
13
15
  sitePlugin(),
@@ -10,6 +10,10 @@ export interface Site {
10
10
  * Additional setup for the app.
11
11
  */
12
12
  setup?(app: App, router: Router): void | Promise<void>;
13
+ /**
14
+ * Additional setup for the sandbox app.
15
+ */
16
+ setupSandbox?(app: App): void | Promise<void>;
13
17
  }
14
18
  /**
15
19
  * Add ability to access the site options (`docs/site/index.ts`)
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@do11y/docs",
3
3
  "description": "A very bare-bones tool to help document Vue components.",
4
- "version": "0.0.11",
4
+ "version": "0.0.12",
5
5
  "type": "module",
6
6
  "repository": {
7
7
  "type": "git",
@@ -38,9 +38,9 @@
38
38
  "front-matter": "^4.0.2",
39
39
  "markdown-it": "^14.1.0",
40
40
  "markdown-it-attrs": "^4.3.1",
41
- "markdown-it-vue-meta": "^0.0.2",
42
41
  "v-custom-block": "^1.0.67",
43
- "@do11y/ui": "0.0.5"
42
+ "vue-component-meta": "^3.1.8",
43
+ "@do11y/ui": "0.0.6"
44
44
  },
45
45
  "devDependencies": {
46
46
  "@tsconfig/node24": "^24.0.3",
@@ -1,8 +1,5 @@
1
1
  <template>
2
- <div class="iframe-wrapper">
3
- <iframe ref="iframe" :title="`Sandbox for ${title}`" :src="url" />
4
- </div>
5
-
2
+ <iframe ref="iframe" :title="`Sandbox for ${title}`" :src="url" />
6
3
  <a :href="url" target="_blank" rel="noopener noreferrer">Open in a new tab</a>
7
4
  </template>
8
5
 
@@ -10,7 +7,15 @@
10
7
  import { computed, ref } from 'vue';
11
8
 
12
9
  const props = defineProps<{
10
+ /**
11
+ * The iframe title.
12
+ */
13
13
  title: string;
14
+
15
+ /**
16
+ * The `id` of the sandbox - which is the filename
17
+ * without the extension `.sandbox.vue`.
18
+ */
14
19
  id: string;
15
20
  }>();
16
21
 
@@ -19,7 +24,7 @@
19
24
  const url = computed(() => `${window.location.origin}/sandbox?id=${props.id}`);
20
25
  </script>
21
26
 
22
- <style scoped>
27
+ <style>
23
28
  iframe {
24
29
  border: none;
25
30
  width: 100%;
@@ -1,26 +1,20 @@
1
1
  <template>
2
2
  <nav>
3
3
  <ul>
4
- <template v-for="route of routes" :key="route.path">
5
- <li>
6
- <router-link :to="route.path">
7
- {{ route.meta.title }}
8
- </router-link>
9
- </li>
10
- </template>
4
+ <li v-for="route of routes" :key="route.path">
5
+ <router-link :to="route.path">
6
+ {{ route.meta.title }}
7
+ </router-link>
8
+ </li>
11
9
  </ul>
12
10
  </nav>
13
11
 
14
- <RouterView />
12
+ <main>
13
+ <RouterView />
14
+ </main>
15
15
  </template>
16
16
 
17
17
  <script lang="ts" setup>
18
18
  import routes from 'do11y:routes';
19
19
  import './style.css';
20
20
  </script>
21
-
22
- <style>
23
- button {
24
- width: max-content;
25
- }
26
- </style>
@@ -4,7 +4,11 @@ export default {
4
4
  Site: () => import('./Site.vue'),
5
5
 
6
6
  async setup(app) {
7
- const SandboxPlaygroundComponent = (await import('./SandboxPlayground.vue')).default;
8
- app.component('SandboxPlayground', SandboxPlaygroundComponent);
7
+ const SandboxIframe = (await import('./SandboxIframe.vue')).default;
8
+ app.component('SandboxIframe', SandboxIframe);
9
+ },
10
+
11
+ async setupSandbox(app) {
12
+ /** Setup sandbox app */
9
13
  },
10
14
  } satisfies Site;
@@ -1,10 +1,3 @@
1
1
  import type { PluginOptions } from '@do11y/docs';
2
2
 
3
- export default {
4
- metaRenderer(meta, title) {
5
- return `
6
- <h3>${title}</h3>
7
- <pre><code>${JSON.stringify(meta, null, 2)}</code></pre>
8
- `;
9
- },
10
- } satisfies PluginOptions;
3
+ export default {} satisfies PluginOptions;
@@ -15,6 +15,7 @@ html {
15
15
  margin: 0;
16
16
  }
17
17
 
18
+ [id],
18
19
  :target {
19
20
  scroll-margin-block: 2em;
20
21
  }
@@ -24,54 +25,17 @@ button {
24
25
  cursor: pointer;
25
26
  }
26
27
 
27
- button {
28
- color: inherit;
29
- }
30
-
31
28
  button:disabled,
32
29
  button[aria-disabled='true'] {
33
30
  cursor: default;
34
31
  }
35
32
 
36
- button,
37
- input,
38
- textarea,
39
- select {
40
- font: inherit;
41
- letter-spacing: inherit;
42
- word-spacing: inherit;
43
- }
44
-
45
- textarea {
46
- field-sizing: content;
47
- }
48
-
49
- a {
50
- text-underline-position: from-font;
51
- }
52
-
53
33
  pre {
54
34
  white-space: pre-wrap;
35
+ inline-size: 100%;
55
36
  }
56
37
 
57
- code {
58
- word-break: break-all;
59
- }
60
-
61
- pre,
62
- table,
63
- img,
64
- svg,
65
- picture,
66
- video,
67
- canvas,
68
- iframe {
69
- max-inline-size: 100%;
70
- min-inline-size: 0;
71
-
72
- display: block;
73
- }
74
-
75
- [id] {
76
- scroll-margin-top: 2rem;
38
+ body {
39
+ margin-inline: auto;
40
+ inline-size: min(90dvw, 50rem);
77
41
  }