Skip to content

Commit

Permalink
feat: improve api parser and json schema for vue (#2051)
Browse files Browse the repository at this point in the history
* feat: add functional component/generic component support

* feat: add more typedoc/jsdoc tags

version control  and release related tags

* fix: expose outside props

* feat: add externalSymbolLinkMap support

* fix: readme

* fix: tests run on windows

* feat: add source reference for interface, type alias, type params

* fix: vue demo

* fix: dynamic git revision

* fix: tests on windows

* refactor: remove version

* feat: use dumi built-in function to generate source links
  • Loading branch information
jeffwcx committed Apr 2, 2024
1 parent 77edfde commit 8cdc32b
Show file tree
Hide file tree
Showing 61 changed files with 4,071 additions and 1,167 deletions.
17 changes: 10 additions & 7 deletions assets-types/typings/atom/index.d.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
import type { ObjectPropertySchema, PropertySchema } from './props';
import type {
FunctionArgSchema,
ObjectPropertySchema,
PropertySchema,
} from './props';

/**
* base atom asset
Expand Down Expand Up @@ -50,9 +54,11 @@ export interface AtomComponentAsset extends AtomBaseAsset {
*/
eventsConfig?: ObjectPropertySchema;
/**
* methods definition of component
* Whether it is methods and properties exposed by component instances,
* or common functional calls, such as Popup.open().
* Such imperative methods and properties should be classified under this configuration
*/
methodsConfig?: ObjectPropertySchema;
imperativeConfig?: ObjectPropertySchema;

/**
* available parent components of component
Expand Down Expand Up @@ -89,10 +95,7 @@ export interface AtomFunctionAsset extends AtomBaseAsset {
/**
* arguments of function
*/
arguments: {
key: string;
schema: PropertySchema;
}[];
arguments: FunctionArgSchema[];

/**
* return value of function
Expand Down
39 changes: 37 additions & 2 deletions assets-types/typings/atom/props/index.d.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,25 @@
import type { BuiltinTags } from './jsdoc';
import type { TypeMap } from './types';

export interface PropertySourceReference {
/**
* fileName of the source file
*/
fileName: string;
/**
* The one based number of the line that emitted the declaration
*/
line: number;
/**
* The index of the character that emitted the declaration
*/
character: number;
/**
* URL for displaying source file, usually the git repo file URL
*/
url?: string;
}

/**
* base props definition
*/
Expand All @@ -25,6 +44,10 @@ export interface BasePropertySchema<T extends keyof TypeMap = keyof TypeMap> {
* value type of prop
*/
type?: T;
/**
* the full name of the type
*/
className?: string;
/**
* const value of prop
*/
Expand All @@ -50,6 +73,10 @@ export interface BasePropertySchema<T extends keyof TypeMap = keyof TypeMap> {
* extra jsdoc tags
*/
tags?: BuiltinTags & Record<string, any>;
/**
* source of prop
*/
source?: PropertySourceReference[];
}

/**
Expand Down Expand Up @@ -115,9 +142,16 @@ export interface ObjectPropertySchema extends BasePropertySchema {
required?: string[];
}

export interface ReferencePropertySchema extends BasePropertySchema {
type: 'reference';
name: string;
typeParameters?: PropertySchema[];
externalUrl: string;
}

export interface FunctionArgSchema {
key: string;
type: PropertySchema | string;
schema: PropertySchema;
hasQuestionToken?: boolean;
}

Expand All @@ -140,4 +174,5 @@ export type PropertySchema =
| FunctionPropertySchema
| StringPropertySchema
| NumberPropertySchema
| BooleanPropertySchema;
| BooleanPropertySchema
| ReferencePropertySchema;
9 changes: 9 additions & 0 deletions docs/theme/default.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,15 @@ dumi 内置了一套完善的默认主题,默认主题的呈现效果与 dumi

当配置为 `true` 时 dumi 会根据项目 `package.json` 中的 `repository` 配置及当前分支,使用 [hosted-git-info](https://github.com/npm/hosted-git-info) 自动生成编辑链接,仅支持[部分代码托管平台](https://github.com/npm/hosted-git-info#supported-hosts);如果你使用的是其他代码托管平台或私有化部署的平台,可以使用字符串模板自定义编辑链接,例如 `https://gitlab.example.com/group/repo/{filename}`,其中 `{filename}` 会被替换为当前文档在仓库中的文件路径。

### sourceLink <Badge>2.3.0+</Badge>

- 类型:`boolean | string`
- 默认值:`true`

主要用于 API Table 中类型的外链,目的是让没有文档的类型,直接导航到仓库中,方便用户参考。

用法与 `editLink` 类似,不过其自定义字符串模板比 `editLink` 多了一个 `{line}``https://gitlab.example.com/group/repo/{filename}?L={line}`

### lastUpdated <Badge>2.2.2+</Badge>

- 类型:`boolean`
Expand Down
12 changes: 12 additions & 0 deletions examples/vue/.dumirc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,18 @@ export default {
presets: [require.resolve('@dumijs/preset-vue')],
vue: {
tsconfigPath: path.resolve(__dirname, './tsconfig.vue.json'),
checkerOptions: {
externalSymbolLinkMappings: {
typescript: {
Promise:
'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise',
},
'@vue/runtime-core': {
VNodeChild:
'https://github.com/vuejs/core/blob/main/packages/runtime-core/src/vnode.ts#L136',
},
},
},
},
themeConfig: {
nav: [
Expand Down
5 changes: 5 additions & 0 deletions examples/vue/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
{
"name": "@examples/vue",
"description": "A Vue3 component library",
"repository": {
"type": "git",
"url": "https://github.com/umijs/dumi",
"directory": "examples/vue"
},
"license": "MIT",
"scripts": {
"build": "node ../../bin/dumi.js build",
Expand Down
60 changes: 33 additions & 27 deletions examples/vue/src/Button/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,34 +48,12 @@ export default {
## Functional Component

```tsx
interface ArticleProps {
title?: string;
desc?: string;
import { Article } from '@examples/vue';
function ArticleWrapper() {
return <Article></Article>;
}

function Article(props: ArticleProps) {
return (
<article>
<h1>{props.title}</h1>
<p>{props.desc}</p>
</article>
);
}

Article.props = {
title: {
type: String,
required: false,
default: 'Functional Component Demo',
},
desc: {
type: String,
required: false,
default: 'No Desc here',
},
};

export default Article;
export default ArticleWrapper;
```

## Button API
Expand All @@ -94,4 +72,32 @@ export default Article;

### Methods

<API id="Button" type="methods"></API>
<API id="Button" type="imperative"></API>

## Article API

## Props

<API id="Article" type="props"></API>

## Events

<API id="Article" type="events"></API>

## Slots

<API id="Article" type="slots"></API>

## List API

:::warning
The List component is defined in the form of `defineComponent(<T>function() {})`, so only Props and Events can be obtained
:::

### Props

<API id="List" type="props"></API>

### Events

<API id="List" type="events"></API>
6 changes: 4 additions & 2 deletions examples/vue/src/Button/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ export const buttonProps = {

/**
* 按钮
* @deprecated 0.2.0版本将会移除
*/
size: {
type: String as PropType<'sm' | 'md' | 'lg'>,
Expand All @@ -32,12 +33,13 @@ export const buttonProps = {
export interface ButtonMethods {
/**
* 聚焦
* @exposed
* @public
*/
focus: () => void;
/**
* 失焦
* @exposed
* @public
* @version 0.0.2
*/
blur: () => void;
}
Expand Down
14 changes: 13 additions & 1 deletion examples/vue/src/Foo/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ import { Button, Badge } from '@examples/vue';
<template>
<Button>
<Badge icon="iframe" />
<Badge icon="🆙">iframe</Badge>
</Button>
</template>
```
Expand All @@ -102,3 +102,15 @@ import { Button, Badge } from '@examples/vue';
### Props

<API id="Badge" type="props"></API>

### Slots

<API id="Badge" type="slots"></API>

### Events

<API id="Badge" type="events"></API>

## useVNode

<API id="useVNode"></API>
70 changes: 70 additions & 0 deletions examples/vue/src/List.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import {
SetupContext,
defineComponent,
onMounted,
ref,
shallowRef,
type SlotsType,
} from 'vue';

export type BaseItem = { id: string | number; text: string };

export interface ListProps<Item extends BaseItem> {
/**
* data source
*/
source: () => Promise<Array<Item>> | Array<Item>;
/**
* trigger when data have been loaded
* @deprecated
*/
onLoaded?: (data: Array<Item>) => void;
}

export interface ListSlotsType<Item extends BaseItem> {
item?: { item: Item };
}

/**
* @component
* Generic components must use `@component`, because defineComponent returns just a plain function
*/
export const List = defineComponent(function <Item extends BaseItem = BaseItem>(
{ source, onLoaded }: ListProps<Item>,
{ slots, expose }: SetupContext<{}, SlotsType<ListSlotsType<Item>>>,
) {
const list = shallowRef<Array<Item>>([]);
const loading = ref(false);

async function load() {
loading.value = true;
const data = await source();
list.value = data;
loading.value = false;
onLoaded?.(data);
}

expose({
// 遗憾的是这种函数定义方式,解析器并不能抽取imperative数据
load,
});

onMounted(async () => {
load();
});
return () => (
<>
{loading.value ? (
'loading...'
) : (
<ul>
{list.value.map((item) => (
<li key={item.id}>
{slots.item ? slots.item({ item }) : item.text}
</li>
))}
</ul>
)}
</>
);
});
Loading

0 comments on commit 8cdc32b

Please sign in to comment.