Open Graphmaxer opened 4 years ago
Yeah, and I also have been meaning to revamp the API table style, any suggestions/screenshots are welcome.
@Graphmaxer You've mentioned keeping the documentation in the .svelte
files using sveltedoc-parser
, but it seems to me the best solution in the long run would be to migrate the components to typescript (<script lang='ts'>
) and use typedoc on them, probably by running it on the content of the <script>
tag (extracted using the svelte parser).
I tested the project with typescript components and both build
and test
are passing. The only part I'm not too sure about yet is how to correctly expose the types for library usage. Importing from svelte-materialify/src
or svelte-materialify/src/components/<ComponentName>
correctly shows the typings from the .svelte
files, but importing from svelte-materialify
still points to svelte-materialify/@types
. Would it be possible to generate d.ts
declaration files from the .svelte
to avoid having to maintain the type files?
I'd like to work on this if you have not already started something. I feel using this approach would be better because it provides both typing and documentation directly in the component file, thus reducing file juggling and documentation duplication.
I agree with you @soft-decay, typescript is probably the good way to document components. I don't know any solution about the library usage, i think the svelte team is also figuring out the best way to distribute libraries with typings (RFC). And feel to free to experiment and try, i'm not working on this currently.
Ok then, we have two approches:
1) Use lang=ts
.
2) Generate .d.ts
files using sveltedoc-parser
Using the 1 method, this will be much better to maintain but we will need to also install typescript when doing an advanced install and I fear the development times would be slower (please correct me if I am wrong). Using the 2 method would be a lot easier but would not provide good definitions. I am personally inclined to the 1 method (we can also provide a custom preprocessor instead of using svelte-preprocess to speed things up?).
Please list anything that I may have missed.
@TheComputerM TL; DR I wanted 1 but I think 2 would work well in the meantime.
I've encountered a few problems while experimenting.
sveltedoc-parser
does not support typescript inside script tags (this feature), which makes the parsing process rather convoluted when using <script lang="ts">
(i.e. You need a different parser for the script block, then transform it and pass it to sveltedoc-parser
, then merge the information from the two parsers and produce a new json
file).<script lang="ts">
produces incomplete/incorrect definitions (e.g. No interface, non-optional props, etc).Because of that, I think it would be best to :
@type
).*.d.ts
files from the sveltedoc-parser
*.json
files. This would be simple using templates (e.g. mustache) but maybe sveltedoc-parser
already can export declaration files? (I did not find that it can)Of course I do not know the full extend of what types you would like to provide, but I think jsdoc could be enough. It would be possible to update the @type {<type>}
annotations to : <type>
when typescript becomes available in sveltedoc-parser
.
So I worked on a declaration (d.ts) generator and I have a first working draft. I would like some input on how to improve it. Here's how it plugs into the api
script:
sveltedoc-parser
using generateJSON
(which now also returns the produced document)generateTypings
){ SvelteComponent } from './shared'
)RippleOptions
)visibility: 'public'
(i.e. exported) props:
?: <type>
)./@types/<ComponentName>.d.ts
A small number of manually created declarations would have to be to kept in a separate folder for step 2.2. I spotted these:
./shared
) in all components./Ripple
)svelte/transition
)You can check the changes I made in PR #76.
I feel like storing all the components in a single .d.ts
file is better. Also everything has to be re-hauled as there is a better way to write definitions now.
Nice work here @soft-decay, I think that the Svelte team is changing to SvelteComponentTyped
instead of SvelteComponent
recently. They are also talking about Svelte 4.0 which probably come with SvelteKit in 2021 and also with typed components. So maybe your work should be used right now because the current api generator is not working. And in the future we should switch to official typed components with Svelte 4.0.
For sure I was not expecting this to be a permanent solution, just a way to reduce maintenance/effort on the typings in the short term. The new SvelteComponentTyped
is a really good thing, but I don't think that it resolves the issue of the api-generator, it just changes the format of the declaration files. The declarations could be generated using the SvelteComponentTyped
declaration and definitely could all be bundled in a single declaration file. It just means adjusting the generation template.
Should I go for it (same steps described above but with SvelteComponentTyped
and all in a single file)? A single file would also remove the need for step 2.ii, which is a nice plus.
For the single file, go for it and for the usage of SvelteComponentTyped
, i don't know if we should switch to this, it is very new and i don't know if the language tools (extension vor vscode) is working properly with it. We should maybe wait and switch to SvelteComponentTyped
in a second step.
From what I tested, SvelteComponentTyped
works out of the box in vscode. It seems like the only requirement is to update dependencies to "svelte": "^3.31.0"
(both dev and peer).
The bundled declarations file is over 2000 lines, but here is a snippet:
import { SvelteComponentTyped } from 'svelte'
import { TransitionConfig, blur, crossfade, draw, fade, fly, scale, slide } from 'svelte/transition'
import { RippleOptions } from './@types/Ripple'
interface AlertProps {
class?: string;
/**
* @default true
*/
visible?: boolean;
transition?: any;
transitionOpts?: any;
/**
* @default false
*/
dense?: boolean;
/**
* @default false
*/
outlined?: boolean;
/**
* @default false
*/
text?: boolean;
/**
* @default false
*/
tile?: boolean;
/**
* @default false
*/
dismissible?: boolean;
/**
* @default false
*/
border?: boolean;
/**
* @default false
*/
coloredBorder?: boolean;
}
export declare class Alert extends SvelteComponentTyped<AlertProps> {}
There is still a lot to be done for the component typings and documentation. I Also included a list of known imports at the start of the bundle.
What else would make it better and easier to use? I'm thinking adding events and slots.
Right now index.d.ts
can be generated with yarn api
.
Looks good to me ! Nice work @soft-decay ! 👍
We can also use the default
attribute of SvelteComponentTyped
for default value of props.
Also we have to parse events, slots and even sass variables (know any good way to do that?).
sveltedoc-parser
, I'll check.This is better for sass https://github.com/mleg/sass-vars-to-js-example, @soft-decay we can customize the variables in svelte materiaify so it is needed to show what variables can be customized.
@soft-decay You can see it here, should with default event/prop/slot.
@Graphmaxer Are you referring to the 3rd generic param? That would be for slots, and the default keyword here refers to the default slot. You can also see it in the declaration. If that is not it, I'm sorry I could not see what you meant.
@TheComputerM typed-scss-modules seems pretty good. I'll try it and see if it works well enough for the project's setup.
@soft-decay Yes exactly, in this RFC, they also say :
This would not be a breaking change to the existing definition because of the any type by default for props/events/slots.
this default
parameter should work with props/events/slots (need testing to be sure).
@Graphmaxer I see what you're saying, but my understanding is that it refers to the default slot, that is, the unnamed slot. For example :
import { SvelteComponentTyped } from 'svelte';
export class MyComponent extends SvelteComponentTyped<{}, {}, { default: { numberProp: number } }> {}
lets you do this (because the unnamed slot is the default slot) :
<script lang="ts">
import { MyComponent } from "myModule";
</script>
<MyComponent let:numberProp>{{ numberProp }}</MyComponent>
But this :
import { SvelteComponentTyped } from 'svelte';
export class MyComponent extends SvelteComponentTyped<{}, {}, { content: { numberProp: number } }> {}
Let you do this :
<script lang="ts">
import { MyComponent } from "myModule";
</script>
<MyComponent>
<div slot="content" let:numberProp>{{ numberProp }}</div>
</MyComponent>
In both case they would be typed as a number
. Let me know if I missed something, but I did not see a way to set default values directly on the type (a example syntax would help understand). Right now they are set throught the @default
jsdoc annotations.
@soft-decay You're right. I misunderstood this default
attribute ^^.
Hi, I'm plan to start implement the TS support in sveltedoc-parser (https://github.com/alexprey/sveltedoc-parser/issues/34), but actually I dont use svelte with TS and it will be very nice if you have few examples with typescript svelte components
Currently we are using sveltedoc-parser to generate JSON files that we can use in the website as API documentation.
Svelte is moving to Typescript and components too. Multiple options are available :
.svelte
file via comments. With thissveltedoc-parser
is fully functional with props/slots/events documentation..d.ts
files. We need to change the script to generate the JSON files. We can use native typescript compiler API, tsdoc parser, api-extractor or typedoc. With this option we can only type props until this get approved or similar.I started to implement a mix between sveltedoc-parser and typescript compiler api in this PR : #25.
Feel free to discuss about it.