Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: improve api parser and json schema for vue #2051

Merged
merged 13 commits into from
Apr 2, 2024
Merged
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;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这个存 assets.json 会比较冗余,在运行时再拼 repository 信息,类似:

href={`${intl.formatMessage(
{ id: '$internal.edit.link' },
{ filename: frontmatter.filename },
)}`}

siteDataContext 里可能得记一下 git tree hash

}

/**
* 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
PeachScript marked this conversation as resolved.
Show resolved Hide resolved
*/
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
Loading