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

Svelte: Svelte syntax Component Story Format (Reupload) #12367

Closed
wants to merge 16 commits into from

Conversation

BlackFenix2
Copy link
Contributor

I Copied the text and filechanges from this abandoned PR: #7682 the original author is @rixo

Issue: #6653

Add support for authoring stories in Svelte format, mirroring MDX story syntax, and exporting result that conforms to CSF. CSF can be imported directly from the *.stories.svelte files thanks to a webpack loader.

Changes have been applied over existing app/svelte and examples/svelte-kitchen-sink to preserve support for legacy format and have everything under a single @storybook/svelte package.

What I did

  • Add a webpack loader that transforms *.stories.svelte to CSF

  • Add Meta and Story svelte components to @storybook/svelte

  • Change presets to include the svelte CSF loader

  • Move existing examples using storiesOf under legacy (still in the same svelte-kitchen-sink example)

  • Add examples using Svelte component syntax

How to test

cd examples/svelte-kitchen-sink
yarn storybook

Details

Following discussion in the issue and my first PR #7023, I have adapted the syntax to mirror that of MDX with Meta and Story components.

Integrating with CSF removed the need for any extra boilerplate (the new architecture also made the integration effort much simpler on my part since all the tricky things that are not framework specific are now handled directly by the core).

Here's an example of the resulting syntax that this gives us:

<script>
  import { Meta, Story } from '@storybooks/svelte'
  import { action } from '@storybook/addon-actions'

  import Button from './Button.svelte'
</script>

<Meta title="My|Stories" parameters={{ ... }} decorators={[ ... ]} />

<Story name"first" parameters={{ ... }} decorators={[ ... ]}>
  <p>Here's the component:</p>
  <Button>Click me!</Button/>
</Story>

<Story name"actions">
  <Button onClick={action('clicked')}>Click me!</Button/>
</Story>

With direct import, we get access to a Svelte component that is a preconfigured preview of the target story:

import { first } from './my.stories.svelte'

const FirstPreview = first() // returns a svelte component

// render the "story preview" (this is regular svelte component API)
const cmp = new FirstPreview({ target: document.body })

Next steps

The most pressing issue that remains to be addressed (IMO) is babel transpilation. Currently, Svelte components are not transpiled down to ES5; we're using the ES2015 output of Svelte compiler directly. Since those components (e.g. Story, Meta) are used in the browser, that imposes a hard limit on the browsers we can support. And, internally, it also causes interop issues between transpiled code and ES2015 code (transpiled classes cannot extend ES classes).

And then testing, interop with addons (source, docs...), MDX support... The babel issue is probably a blocker for some of these too.

I Copied the PR to keep the conversation about writing stories with svelte syntax alive, let me know if you have any questions

@github-actions
Copy link
Contributor

github-actions bot commented Sep 3, 2020

Fails
🚫 PR is marked with "in progress" label.

Generated by 🚫 dangerJS against ce04d98

@BlackFenix2
Copy link
Contributor Author

i just learned from Svelte's Discord, in vscode you can press F1 and the svelte extension can show you the compiled code. that should make it easier to debug the .svelte transfromations to CSF

@BlackFenix2
Copy link
Contributor Author

ok, i did enough to support CSF stories in .svelte files. the Syntax/API is similar to javascript CSF, only the component is used in place of 'export default {}'.

for control autogeneration support, it is stuck on one default component per story file so the button component args wont generate (for now).

I has to tweak and cleanup a bit of bloat code/components, you can try the results on the netlify preview. The code should be ready for review/merge now.

javascript (typescript) CSF:

import ControlShowcaseView from './views/ControlShowcaseView.svelte';

export default {
  title: 'Addon/Controls',
  component: ControlShowcaseView,
  argTypes: {
    range: { defaultValue: 0, control: { type: 'range', min: 0, max: 100 } },
    loadingState: {
      control: {
        type: 'inline-radio',
        options: ['loading', 'error', 'ready'],
      },
    },
    food: {
      control: {
        type: 'inline-check',
        options: ['apple', 'banana', 'orange'],
      },
    },
    car: {
      control: {
        type: 'select',
        options: ['Truck', 'SUV', 'Tesla'],
      },
    },
    color: {
      control: 'color',
    },
    date: {
      control: 'date',
    },
  },
};

export const ShowCase = (args) => ({
  Component: ControlShowcaseView,
  props: args,
});

Svelte Syntax:

<script>
  import ControlShowcaseView from './views/ControlShowcaseView.svelte';
  import { Meta, Story } from '@storybook/svelte';
  import { action } from '@storybook/addon-actions';
  import { withKnobs, text, number } from '@storybook/addon-knobs';
  import Button from '../components/Button.svelte';

  const parameters = {
    storySource: {
      source: 'insert source code here :(',
    },
  };

  const argTypes = {
    range: { defaultValue: 0, control: { type: 'range', min: 0, max: 100 } },
    loadingState: {
      control: {
        type: 'inline-radio',
        options: ['loading', 'error', 'ready'],
      },
    },
    food: {
      control: {
        type: 'inline-check',
        options: ['apple', 'banana', 'orange'],
      },
    },
    car: {
      control: {
        type: 'select',
        options: ['Truck', 'SUV', 'Tesla'],
      },
    },
    color: {
      control: 'color',
    },
    date: {
      control: 'date',
    },
  };
</script>

<Meta title="Svelte Syntax" component={ControlShowcaseView} {argTypes} />
<Story name="with Controls">
  <ControlShowcaseView />
</Story>

@stale
Copy link

stale bot commented Oct 12, 2020

Hi everyone! Seems like there hasn't been much going on in this issue lately. If there are still questions, comments, or bugs, please feel free to continue the discussion. Unfortunately, we don't have time to get to every issue. We are always open to contributions so please send us a pull request if you would like to help. Inactive issues will be closed after 30 days. Thanks!

@stale stale bot added the inactive label Oct 12, 2020
@stale stale bot removed the inactive label Oct 12, 2020
@xow
Copy link

xow commented Nov 17, 2020

Let me know if I can help this get through in any way. Cheers!

@BlackFenix2
Copy link
Contributor Author

@xow Im pretty much done here, not sure what else is needed to merge the PR.

@savgrace
Copy link

savgrace commented Jan 5, 2021

Thanks for the work on this @BlackFenix2 ! I'd love to see this get merged 🥰

@j3rem1e
Copy link
Contributor

j3rem1e commented Jan 22, 2021

Hello, and thanks for your work !

However, I don't understand your implementation : the main slot doesn't seem to be used ? It isn't instanciated in the code, and I can't make it work in my branch (whatever I wrote under , only the main component is rendered).

Another question: does it work with args or source-loader ?

Thanks again :)

@phated
Copy link
Contributor

phated commented Feb 24, 2021

Closing in favor of storybookjs/addon-svelte-csf#1

@phated phated closed this Feb 24, 2021
@stof stof deleted the svelte-csf branch May 25, 2022 09:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants