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;
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
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>
)}
</>
);
});
53 changes: 53 additions & 0 deletions examples/vue/src/functional.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import { FunctionalComponent as FC } from 'vue';
export interface ArticleProps {
/**
* 文章标题
* @beta
PeachScript marked this conversation as resolved.
Show resolved Hide resolved
* @default "Functional Component Demo"
*/
title?: string;
/**
* 文章描述
* @since 0.0.1
* @default "No Desc here"
*/
desc?: string;

/**
* 点击事件
* @since 0.0.1
*/
onClick?: (e: Event) => void;
}

export interface ArticleSlots {
default?: any;
}

const Article: FC<ArticleProps, {}, ArticleSlots> = function (
props,
{ slots },
) {
return (
<article onClick={props.onClick}>
<h1>{props.title}</h1>
<p>{props.desc}</p>
{slots.default && <p>{slots.default()}</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;
8 changes: 8 additions & 0 deletions examples/vue/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
import { h } from 'vue';

export { default as Button } from './Button';
export { default as Foo } from './Foo';
export * from './List';
export { default as Article } from './functional';
export { default as Badge } from './my-badge.vue';

export function useVNode() {
return h('div');
}
Loading
Loading