storybookjs / storybook

Storybook is the industry standard workshop for building, documenting, and testing UI components in isolation
https://storybook.js.org
MIT License
83.64k stars 9.16k forks source link

Property descriptions missing from Docs Page on Svelte + TypeScript #15891

Open notpushkin opened 2 years ago

notpushkin commented 2 years ago

Describe the bug When a Svelte component is using plain JavaScript, its property descriptions are extracted from JSDoc blocks inside the component. However, if you switch <script> with <script lang="ts"> (and optionally adding some types in there), it stops picking up anything at all.

To Reproduce https://github.com/notpushkin/repro-storybook-svelte-typescript

git clone https://github.com/notpushkin/repro-storybook-svelte-typescript.git
cd repro-storybook-svelte-typescript
yarn
yarn storybook

System

Environment Info:

  System:
    OS: Linux 5.4 Ubuntu 20.04.2 LTS (Focal Fossa)
    CPU: (4) x64 Intel(R) Core(TM) i5-2520M CPU @ 2.50GHz
  Binaries:
    Node: 14.17.5 - /usr/bin/node
    Yarn: 1.22.5 - /usr/bin/yarn
    npm: 6.14.14 - /usr/bin/npm
  Browsers:
    Firefox: 91.0
  npmPackages:
    @storybook/addon-actions: ^6.4.0-alpha.30 => 6.4.0-alpha.30 
    @storybook/addon-essentials: ^6.4.0-alpha.30 => 6.4.0-alpha.30 
    @storybook/addon-links: ^6.4.0-alpha.30 => 6.4.0-alpha.30 
    @storybook/addon-svelte-csf: ^1.1.0 => 1.1.0 
    @storybook/svelte: ^6.4.0-alpha.30 => 6.4.0-alpha.30 

Additional context Possibly related? #14876

notpushkin commented 2 years ago

(Dropping type="ts" and using the @type JSDoc tag seems like a plausible workaround for this.)

MasonOh91 commented 2 years ago

Thanks for logging this, was just running into this issue. I've noticed that I can leave the lang="ts", but the moment I add a type definition to a prop via export backgroundColor: string = null, the docs stop being generated.

The workaround outlined above works great specifically for Storybook docs, but to my knowledge removes the functional aspect of formally typing the properties when using the component outside of Storybook.

notpushkin commented 2 years ago

@MasonOh91 At least, VS Code does treat those correctly – I'm not particularly sure if they are treated in any way different by other TypeScript implementations but JSDoc support is in the official TS docs so I guess it should do for most editors and tools. Does it not work for you?

MasonOh91 commented 2 years ago

@notpushkin It works as far as documenting the property etc, but by just using the TS doc vs typing something via export backgroundColor: string (for example), I then don't get TS errors in-editor if backgroundColor wasn't set to a string. Unless I'm missing something/some VSCode plugin 🤔

pmalacho-mit commented 2 years ago

Hello! Has anyone had the chance to look into this? I'm using 6.5.0-alpha.49 and no js doc info is pulled when my script tag is marked as lang=ts (regardless of if the variable has a type declaration).

It definitely is my preference to be able to use typescript as expected and have my js doc comments pulled into the storybook UI. The automatic documentation is such a cool feature! Definitely unfortunate to have to choose between it and using typescript in svelte components.

IanVS commented 2 years ago

You can track https://github.com/alexprey/sveltedoc-parser/issues/34 for typescript support in the package we use to extract docs information from svelte files.

CallumHoward commented 2 years ago

It makes sense that the TS Parser is not yet ready for prime time, but I am puzzled why the story docs attribute can't be set in the parameters within a story like:

export const Primary = (args) => ({
  Component: Counter,
  props: {
    ...args,
  },
  parameters: {
    docs: {
      description: {
        story: "hello foo bar baz",
      },
    },
  },
});

or with addon-svelte-csf like:

<Story
  name="Primary"
  args={{
    count: 5,
  }}
  parameters={{
    docs: {
      description: {
        story: "Testing 123",
      },
    },
  }}
/>

In both cases it doesn't render the doc description for the story, although it does render the doc description for the component.

Ddupasquier commented 1 year ago

Did anything ever come of this?

shilman commented 1 year ago

cc @JReinhold

JReinhold commented 1 year ago

This is still a current limitation of sveltedoc-parser, which unfortunately looks to be unmaintained. There's still no better alternative out there, except for the official Svelte Language Server, but that would require Storybook's argType inference to be able to interface with a server, which is currently not possible.

As for @CallumHoward's issue:

It makes sense that the TS Parser is not yet ready for prime time, but I am puzzled why the story docs attribute can't be set in the parameters within a story like:

That should be working as of v7.0

rgon commented 1 year ago

@Ddupasquier JSdoc automatic property description generation works fine with storybook 7.0.8 & addon-svelte-csf 3.0.2. See my component.svelte:

<script lang="ts">
    // Source of the asset
    export let src:string = ''
</script>
...
01oseluiz commented 1 year ago

This isn't an issue related with sveltedoc-parser lib.

If you are using svelte with vite and storybook with vite for svelte, do that:

  1. run npm i svelte-preprocess
  2. Change on svelte.config.js the import { vitePreprocess } from '@sveltejs/vite-plugin-svelte' to import preprocess from "svelte-preprocess"
  3. Change the preprocess: vitePreprocess(), to preprocess: preprocess(),

The new svelte template use vitePreprocess from '@sveltejs/vite-plugin-svelte'. This preprocessor removes the comments.

The svelte-docgen.ts used by storybook to parse the file and extract the autodoc object uses the configured preprocessor on your svelte.config.js. Since vitePreprocess remove the comments, the svelte-docgen can't do its job.

Changing the preprocessor have some implications, you can check more here: https://github.com/sveltejs/vite-plugin-svelte/blob/main/docs/preprocess.md

Indeed sveltedoc-parser lib has an issue related with typescript as described here: https://github.com/storybookjs/storybook/issues/16609

Example

import fs from 'fs';
import path from 'path';
import { preprocess } from 'svelte/compiler';
import sveltePreprocess from "svelte-preprocess";
import { vitePreprocess } from '@sveltejs/vite-plugin-svelte'

const cwd = process.cwd();
const resource = path.relative(cwd, "src/stories/Button.svelte");
const src = fs.readFileSync(resource).toString();

const { code: fileContent } = await preprocess(src, vitePreprocess(), {
    filename: resource
});

const { code: fileContent2 } = await preprocess(src, sveltePreprocess(), {
    filename: resource
});

console.log(fileContent)
console.log(fileContent2)

output with vite preprocess:

<script lang="ts">import "./button.css";
export let primary = false;
export let backgroundColor = void 0;
export let size = "medium";
export let label = "";
$:
  mode = primary ? "storybook-button--primary" : "storybook-button--secondary";
$:
  style = backgroundColor ? `background-color: ${backgroundColor}` : "";
</script>

<button
  type="button"
  class={['storybook-button', `storybook-button--${size}`, mode].join(' ')}
  {style}
  on:click
>
  {label}
</button>

output with svelte preprocess:

<script lang="ts">import './button.css';
/**
 * Is this the principal call to action on the page?
 */
export let primary = false;
/**
 * What background color to use
 */
export let backgroundColor = undefined;
/**
 * How large should the button be?
 */
export let size = 'medium';
/**
 * Button contents
 */
export let label = '';
$: mode = primary ? 'storybook-button--primary' : 'storybook-button--secondary';
$: style = backgroundColor ? `background-color: ${backgroundColor}` : '';
</script>

<button
  type="button"
  class={['storybook-button', `storybook-button--${size}`, mode].join(' ')}
  {style}
  on:click
>
  {label}
</button>
JReinhold commented 11 months ago

Thanks for the insights @01oseluiz, that's very interesting. This is a big frustration for users, I'm happy to know there's a workaround.

@benmccann do you see a way forward here where users wouldn't need to do the workaround described above, or is this just how it is and that we need to document it?

Given that sveltedoc-parser is still unmaintained I wouldn't expect Svelte to change behavior to make it work, but I don't know if we could do anything on the Storybook side?