Skip to content

Commit

Permalink
Merge pull request #26424 from storybookjs/framework-doc-remaining
Browse files Browse the repository at this point in the history
Docs: Bring frameworks docs to `next`
  • Loading branch information
kylegach authored Mar 12, 2024
2 parents ec3f7ce + c5cf84f commit 3e20a1f
Show file tree
Hide file tree
Showing 37 changed files with 1,240 additions and 332 deletions.
33 changes: 2 additions & 31 deletions code/frameworks/svelte-webpack5/README.md
Original file line number Diff line number Diff line change
@@ -1,32 +1,3 @@
# Storybook for Svelte
# Storybook for Svelte & Webpack

Storybook for Svelte is a UI development environment for your Svelte components.
With it, you can visualize different states of your UI components and develop them interactively.

![Storybook Screenshot](https://github.com/storybookjs/storybook/blob/main/media/storybook-intro.gif)

Storybook runs outside of your app.
So you can develop UI components in isolation without worrying about app specific dependencies and requirements.

## Getting Started

```sh
cd my-svelte-app
npx storybook@latest init
```

For more information visit: [storybook.js.org](https://storybook.js.org)

---

Storybook also comes with a lot of [addons](https://storybook.js.org/addons) and a great API to customize as you wish.
You can also build a [static version](https://storybook.js.org/docs/svelte/sharing/publish-storybook) of your Storybook and deploy it anywhere you want.

## TODOs

- Support `addon-info`
- Support Svelte markup directly in stories
- Add Svelte storybook generator
- Provide stories that show advanced Svelte use cases
- Hydratable
- Advanced mount options
See [documentation](https://storybook.js.org/docs/8.0/get-started/svelte-webpack5?renderer=svelte) for installation instructions, usage examples, APIs, and more.
188 changes: 2 additions & 186 deletions code/frameworks/sveltekit/README.md
Original file line number Diff line number Diff line change
@@ -1,190 +1,6 @@
# Storybook for SvelteKit <!-- omit in toc -->
# Storybook for SvelteKit

Our goal is to help you use the tools you love together with Storybook. That’s why Storybook has zero-config support for SvelteKit with the `@storybook/sveltekit` package.

Check out our [Frameworks API](https://storybook.js.org/blog/framework-api/) announcement for what this all means for you and our continued efforts to make Storybook a seamless integration for any project.

## Table of Contents <!-- omit in toc -->

- [Supported features](#supported-features)
- [Requirements](#requirements)
- [Getting Started](#getting-started)
- [In a project without Storybook](#in-a-project-without-storybook)
- [In a project with Storybook](#in-a-project-with-storybook)
- [Automatic migration](#automatic-migration)
- [Manual migration](#manual-migration)
- [How to mock](#how-to-mock)
- [Mocking links](#mocking-links)
- [Troubleshooting](#troubleshooting)
- [Error: `ERR! SyntaxError: Identifier '__esbuild_register_import_meta_url__' has already been declared` when starting Storybook](#error-err-syntaxerror-identifier-__esbuild_register_import_meta_url__-has-already-been-declared-when-starting-storybook)
- [Acknowledgements](#acknowledgements)

## Supported features

All Svelte language features are supported out of the box, as Storybook uses the Svelte compiler underneath.
However SvelteKit has some [Kit-specific modules](https://kit.svelte.dev/docs/modules) that currently aren't supported. It's on our roadmap to support most of them soon:

| **Module** | **Status** | **Note** |
| ---------------------------------------------------------------------------------- | ---------------------- | ----------------------------------------------------------------------------------------------------------------------------------- |
| [`$app/environment`](https://kit.svelte.dev/docs/modules#$app-environment) | ✅ Supported | `version` is always empty in Storybook. |
| [`$app/forms`](https://kit.svelte.dev/docs/modules#$app-forms) | ✅ Supported | See [How to mock](#how-to-mock) |
| [`$app/navigation`](https://kit.svelte.dev/docs/modules#$app-navigation) | ✅ Supported | See [How to mock](#how-to-mock) |
| [`$app/paths`](https://kit.svelte.dev/docs/modules#$app-paths) | ✅ Supported | Requires SvelteKit 1.4.0 or newer |
| [`$app/stores`](https://kit.svelte.dev/docs/modules#$app-stores) | ✅ Supported | See [How to mock](#how-to-mock) |
| [`$env/dynamic/private`](https://kit.svelte.dev/docs/modules#$env-dynamic-private) | ⛔ Not supported | They are meant to only be available server-side, and Storybook renders all components on the client. |
| [`$env/dynamic/public`](https://kit.svelte.dev/docs/modules#$env-dynamic-public) | 🚧 Partially supported | Only supported in development mode. Storybook is built as a static app with no server-side API so cannot dynamically serve content. |
| [`$env/static/private`](https://kit.svelte.dev/docs/modules#$env-static-private) | ⛔ Not supported | They are meant to only be available server-side, and Storybook renders all components on the client. |
| [`$env/static/public`](https://kit.svelte.dev/docs/modules#$env-static-public) | ✅ Supported | |
| [`$lib`](https://kit.svelte.dev/docs/modules#$lib) | ✅ Supported | |
| [`$service-worker`](https://kit.svelte.dev/docs/modules#$service-worker) | ⛔ Not supported | They are only meant to be used in service workers |
| [`@sveltejs/kit/*`](https://kit.svelte.dev/docs/modules#sveltejs-kit) | ✅ Supported | |

This is just the beginning. We're close to adding basic support for many of the SvelteKit features. Longer term we're planning on making it an even better experience to [build](https://storybook.js.org/docs/svelte/writing-stories), [test](https://storybook.js.org/docs/svelte/writing-tests) and [document](https://storybook.js.org/docs/svelte/writing-docs) all the SvelteKit goodies like [pages](https://kit.svelte.dev/docs/routing), [forms](https://kit.svelte.dev/docs/form-actions) and [layouts](https://kit.svelte.dev/docs/routing#layout) in Storybook, while still integrating with all the addons and workflows you know and love.

## Requirements

- [SvelteKit](https://kit.svelte.dev/) >= 1.0.0 (not including beta versions)
- [Storybook](https://storybook.js.org/) >= 7.x

## Getting Started

### In a project without Storybook

Run the following command in your SvelteKit project's root directory, and follow the prompts:

```bash
npx storybook@latest init
```

[More on getting started with Storybook](https://storybook.js.org/docs/svelte/get-started/install)

### In a project with Storybook

This framework is designed to work with Storybook 7. If you’re not already using v7, upgrade with this command:

```bash
npx storybook@latest upgrade
```

#### Automatic migration

When running the `upgrade` command above you should get a prompt asking you to migrate to `@storybook/sveltekit`, which should handle everything for you. In some cases it can't migrate for you, eg. if your existing Storybook setup is based on Webpack. In such cases, refer to the manual migration below.

Storybook 7.0 automatically loads your Vite config, and by extension your Svelte config. If you had a `svelteOptions` property in `.storybook/main.js` the automigration will have removed it, as it is no longer supported.

#### Manual migration

Install the framework:

```bash
yarn add -D @storybook/sveltekit
```

Update your `main.js` to change the framework property:

```js
// .storybook/main.js
export default {
...
framework: '@storybook/sveltekit',
};
```

Storybook 7.0 automatically loads your Vite config, and by extension your Svelte config. If you have a `svelteOptions` property in `.storybook/main.js` you need to remove that. See [Troubleshooting](#error-about-__esbuild_register_import_meta_url__-when-starting-storybook) below.

Remove any redundant dependencies, if you have them:

```bash
yarn remove @storybook/svelte-vite
yarn remove @storybook/svelte-webpack5
yarn remove storybook-builder-vite
yarn remove @storybook/builder-vite
```

## How to mock

To mock a SvelteKit import you can set it on `parameters.sveltekit_experimental`:

```ts
export const MyStory = {
parameters: {
sveltekit_experimental: {
stores: {
page: {
data: {
test: 'passed',
},
},
navigating: {
route: {
id: '/storybook',
},
},
updated: true,
},
},
},
};
```

You can add the name of the module you want to mock to `parameters.sveltekit_experimental` (in the example above we are mocking the `stores` module which correspond to `$app/stores`) and then pass the following kind of objects:

| Module | Path in parameters | Kind of objects |
| ------------------------------------------------- | ------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------- |
| `import { page } from "$app/stores"` | `parameters.sveltekit_experimental.stores.page` | A Partial of the page store |
| `import { navigating } from "$app/stores"` | `parameters.sveltekit_experimental.stores.navigating` | A Partial of the navigating store |
| `import { updated } from "$app/stores"` | `parameters.sveltekit_experimental.stores.updated` | A boolean representing the value of updated (you can also access `check()` which will be a noop) |
| `import { goto } from "$app/navigation"` | `parameters.sveltekit_experimental.navigation.goto` | A callback that will be called whenever goto is called, in no function is provided an action will be logged to the Actions panel |
| `import { pushState } from "$app/navigation"` | `parameters.sveltekit_experimental.navigation.pushState` | A callback that will be called whenever pushState is called, in no function is provided an action will be logged to the Actions panel |
| `import { replaceState } from "$app/navigation"` | `parameters.sveltekit_experimental.navigation.replaceState` | A callback that will be called whenever replaceState is called, in no function is provided an action will be logged to the Actions panel |
| `import { invalidate } from "$app/navigation"` | `parameters.sveltekit_experimental.navigation.invalidate` | A callback that will be called whenever invalidate is called, in no function is provided an action will be logged to the Actions panel |
| `import { invalidateAll } from "$app/navigation"` | `parameters.sveltekit_experimental.navigation.invalidateAll` | A callback that will be called whenever invalidateAll is called, in no function is provided an action will be logged to the Actions panel |
| `import { afterNavigate } from "$app/navigation"` | `parameters.sveltekit_experimental.navigation.afterNavigate` | An object that will be passed to the afterNavigate function (which will be invoked onMount) called |
| `import { enhance } from "$app/forms"` | `parameters.sveltekit_experimental.forms.enhance` | A callback that will called when a form with `use:enhance` is submitted |

All the other functions are still exported as `noop` from the mocked modules so that your application will still work.

### Mocking links

The default link-handling behavior (ie. clicking an `<a />` tag with an `href` attribute) is to log an action to the Actions panel.

You can override this by setting an object on `parameter.sveltekit_experimental.hrefs`, where the keys are strings representing an href and the values are objects typed as `{ callback: (href, event) => void, asRegex?: boolean }`.

If you have an `<a />` tag inside your code with the `href` attribute that matches one or more of the links defined (treated as regex based on the `asRegex` property) the corresponding `callback` will be called.

Example:

```ts
export const MyStory = {
parameters: {
sveltekit_experimental: {
hrefs: {
'/basic-href': (to, event) => {
console.log(to, event);
},
'/root.*': {
callback: (to, event) => {
console.log(to, event);
},
asRegex: true,
},
},
},
},
};
```

## Troubleshooting

### Error: `ERR! SyntaxError: Identifier '__esbuild_register_import_meta_url__' has already been declared` when starting Storybook

> When starting Storybook after upgrading to v7.0, it breaks with the following error:
>
> ```
> ERR! SyntaxError: Identifier '__esbuild_register_import_meta_url__' has already been declared
> ```
You'll get this error when manually upgrading from 6.5 to 7.0. You need to remove the `svelteOptions` property in `.storybook/main.js`, as that is not supported by Storybook 7.0 + SvelteKit. The property is also not necessary anymore because the Vite and Svelte configurations are loaded automatically in Storybook 7.0.
See [documentation](https://storybook.js.org/docs/8.0/get-started/sveltekit?renderer=svelte) for installation instructions, usage examples, APIs, and more.

## Acknowledgements

Expand Down
43 changes: 1 addition & 42 deletions code/frameworks/vue3-webpack5/README.md
Original file line number Diff line number Diff line change
@@ -1,44 +1,3 @@
# Storybook for Vue 3 and Webpack

Storybook for Vue 3 is a UI development environment for your Vue 3 components.
With it, you can visualize different states of your UI components and develop them interactively.

![Storybook Screenshot](https://github.com/storybookjs/storybook/blob/main/media/storybook-intro.gif)

Storybook runs outside of your app.
So you can develop UI components in isolation without worrying about app specific dependencies and requirements.

## Getting Started

```sh
cd my-vue3-app
npx storybook@latest init
```

For more information visit: [storybook.js.org](https://storybook.js.org)

---

Storybook also comes with a lot of [addons](https://storybook.js.org/addons) and a great API to customize as you wish.
You can also build a [static version](https://storybook.js.org/docs/sharing/publish-storybook) of your Storybook and deploy it anywhere you want.

## Extending the Vue application

Storybook creates a [Vue 3 application](https://vuejs.org/api/application.html#application-api) for your component preview.
When using global custom components (`app.component`), directives (`app.directive`), extensions (`app.use`), or other application methods, you will need to configure those in the `./storybook/preview.js` file.

Therefore, Storybook provides you with a `setup` function exported from this package, which receives as a callback your Storybook instance, which you can interact with and add your custom configuration.

```js
// .storybook/preview.js

import { setup } from '@storybook/vue3';

setup((app) => {
app.use(MyPlugin);
app.component('my-component', MyComponent);
app.mixin({
/* My mixin */
});
});
```
See [documentation](https://storybook.js.org/docs/8.0/get-started/vue3-webpack5?renderer=vue) for installation instructions, usage examples, APIs, and more.
4 changes: 3 additions & 1 deletion code/frameworks/web-components-vite/README.md
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
# Storybook for Web components
# Storybook for Web components & Vite

See [documentation](https://storybook.js.org/docs/8.0/get-started/web-components-vite?renderer=web-components) for installation instructions, usage examples, APIs, and more.
72 changes: 2 additions & 70 deletions code/frameworks/web-components-webpack5/README.md
Original file line number Diff line number Diff line change
@@ -1,71 +1,3 @@
# Storybook for web-components
# Storybook for Web components & Webpack

---

Storybook for web-components is a UI development environment for your plain web-component snippets.
With it, you can visualize different states of your UI components and develop them interactively.

![Storybook Screenshot](https://github.com/storybookjs/storybook/blob/main/media/storybook-intro.gif)

Storybook runs outside of your app.
So you can develop UI components in isolation without worrying about app specific dependencies and requirements.

## Getting Started

```sh
cd my-app
npx storybook@latest init -t web_components
```

For more information visit: [storybook.js.org](https://storybook.js.org)

---

Storybook also comes with a lot of [addons](https://storybook.js.org/addons) and a great API to customize as you wish.
You can also build a [static version](https://storybook.js.org/docs/web-components/sharing/publish-storybook) of your storybook and deploy it anywhere you want.

# Hot Module Reloading (HMR)

As web components register on a global registry which only accepts a certain name/class once it can lead to errors when using classical HMR. There are ideas on how to archive HMR with a static registry but there is no proven solution yet. Therefore the best approach for now is to do full page reloads. If you keep your stories to specific states of components (which we would recommend anyways) this usually means it is fast.

# Setup es6/7 dependencies

By default storybook only works with precompiled ES5 code but as most web components themselves and their libs are distributed as ES2017 you will need to manually mark those packages as "needs transpilation".

For example if you have a library called `my-library` which is in ES2017 then you can add it like so

```js
// .storybook/main.js

export default {
webpackFinal: async (config) => {
// find web-components rule for extra transpilation
const webComponentsRule = config.module.rules.find(
(rule) => rule.use && rule.use.options && rule.use.options.babelrc === false
);
// add your own `my-library`
webComponentsRule.test.push(new RegExp(`node_modules(\\/|\\\\)my-library(.*)\\.js$`));

return config;
},
};
```

By default the following folders are included

- `src/*.js`
- `packages/*/src/*.js`
- `node_modules/lit-html/*.js`
- `node_modules/lit-element/*.js`
- `node_modules/@open-wc/*.js`
- `node_modules/@polymer/*.js`
- `node_modules/@vaadin/*.js`

As you can see the `src` folder is also included.
The reason for that is as it has some extra configuration to allow for example `import.meta`.
If you use a different folder you will need to make sure webpack/babel can handle it.

# FAQ

- While working on my component I get the error `Failed to execute 'define' on 'CustomElementRegistry': the name "..." has already been used with this registry`
=> please see <a href="#user-content-setup-page-reload-via-hmr">Setup page reload via HMR</a>
See [documentation](https://storybook.js.org/docs/8.0/get-started/web-components-webpack5?renderer=web-components) for installation instructions, usage examples, APIs, and more.
Loading

0 comments on commit 3e20a1f

Please sign in to comment.