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

Request: typescript usage examples #162

Open
Masstronaut opened this issue Dec 21, 2023 · 4 comments
Open

Request: typescript usage examples #162

Masstronaut opened this issue Dec 21, 2023 · 4 comments
Labels
enhancement New feature or request legacy Related to the legacy version(s)

Comments

@Masstronaut
Copy link

Masstronaut commented Dec 21, 2023

The docs don't have great examples demonstrating how to use the svelte CSF with typescript support. as an example, with <Meta> now deprecated in favor of

<script context="module">
export const meta = { //... 
}
</script>

It would be great to have an example of how to correctly type this (and possibly add the necessary typescript typings as well). I would imagine it should look something like this, but as far as I can tell there is only MetaProps which is not a generic so isn't really type safe for a specific component (ie args):

<script context="module" lang="ts">
import type {MetaProps} from "@storybookjs/addon-svelte-csf"
import MyComponent from "./MyComponent.svelte"
export const meta = ({
 // ...
}) satisfies MetaArgs<MyComponent>;
</script>

If someone can point me to the right type I'm happy to make a PR for the docs changes myself.

Similarly, it would be great to have a generic typing for StoryProps for the same reason.

@Masstronaut Masstronaut added the bug Something isn't working label Dec 21, 2023
@JReinhold JReinhold added enhancement New feature or request and removed bug Something isn't working labels Jan 23, 2024
@sacrosanctic
Copy link

<script	context="module" lang="ts">
import type { Meta } from '@storybook/svelte'
import MyComponent from './MyComponent.svelte'

export const meta: Meta = {
  // ...
}
</script>

Is this the same thing?

@xeho91
Copy link
Collaborator

xeho91 commented May 25, 2024

<script	context="module" lang="ts">
import type { Meta } from '@storybook/svelte'
import MyComponent from './MyComponent.svelte'

export const meta: Meta = {
  // ...
}
</script>

Is this the same thing?

Late to the party, but the correct usage would be:

<script	context="module" lang="ts">
import type { Meta } from '@storybook/svelte'
import MyComponent from './MyComponent.svelte'

- export const meta: Meta = {
+ export const meta = {
  // ...
- }
+ } satisfies Meta<MyComponent>;
</script>

@Masstronaut
Copy link
Author

Okay I've looked at it again and believe I've figured out how to get everything typed. Can you confirm this looks correct to you @xeho91 ?

<!-- MyComponent.stories.svelte -->
<script lang="ts" context="module">
  import MyComponent from './MyComponent.svelte';
  import type { Meta } from '@storybook/svelte';
  export const meta = {
    component: MyComponent,
    // title, parameters, etc... 
  } satisfies Meta<MyComponent>;
</script>
<script lang="ts">
  import { Story, Template } from '@storybook/addon-svelte-csf';
  import type { StoryObj } from '@storybook/svelte';

  type StoryArgs = StoryObj<typeof Meta>;

  const aStory = {
    args: {
      // component props for this story go here
    },
    // NOTE: Specifying the name here causes storybook to fail to dynamically import the component
    // name: "MyComponent story"
  } satisfies StoryArgs;
</script>

<!-- setup the template for rendering stories -->
<Template let:args>
  <MyComponent {...args} />
</Template>

<!-- Uses the template. Note the name MUST be specified here, not in the StoryArgs objects -->
<Story name="MyComponent story" {...aStory} />

This seems to be fully typed on my end, with the caveat (bug?) that setting name or storyName on a StoryArgs object instead of directly on a <Story name="..."> tag causes the storybook renderer to fail.

If you're happy with this usage/example I'm happy to open a PR updating the example stories and readme to reflect this usage.

@JReinhold
Copy link
Collaborator

That looks correct from a typings perspective, it does have some caveats though. As you've found out, name has to be defined as a direct prop, as do template and tags, as we do static analysis to extract those on the server.

Feel free to open a PR to document this.

As a sidenote, the name StoryArgs feels off, as it contains args as property and other things. StoryProps might be better?

Finally, the upcoming major version of the addon that supports Svelte 5 will have a different API that is a lot more typesafe by default without these workarounds. See #191

@xeho91 xeho91 added the legacy Related to the legacy version(s) label Nov 5, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request legacy Related to the legacy version(s)
Projects
None yet
Development

No branches or pull requests

4 participants