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

Lit: Initial lit2 support #14600

Merged
merged 28 commits into from
May 10, 2021
Merged
Show file tree
Hide file tree
Changes from 10 commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
f038204
feat(lit): add initial kitchen sink for lit
Apr 1, 2021
a465415
feat(lit): add lit package, setup eslint configs, initial render works
Apr 2, 2021
ca6e3ff
Merge branch 'next' into @storybook/lit
gaetanmaisse Apr 16, 2021
0a5835c
refactor(lit): activate TS strict mode and fix errors
gaetanmaisse Apr 16, 2021
f7d9e79
docs(lit): remove ref to web components and add a big warning
gaetanmaisse Apr 16, 2021
3481417
example(lit): remove addon knob as it will be deprecated in favor of …
gaetanmaisse Apr 16, 2021
3929d2e
fixup! example(lit): remove addon knob as it will be deprecated in fa…
gaetanmaisse Apr 16, 2021
c60c7d3
refactor(docs): remove babel-loader peer dep
gaetanmaisse Apr 18, 2021
a652a01
refactor(builders): require react in the SB app context as it is prov…
gaetanmaisse Apr 18, 2021
fd0fa99
example(lit): move the example out the Yarn workspaces of the monorepo
gaetanmaisse Apr 18, 2021
35916b9
Merge branch 'next' into @storybook/lit
gaetanmaisse Apr 23, 2021
3158799
example(lit): update to lit rc and fix stories
gaetanmaisse Apr 23, 2021
dcca003
Merge branch 'next' into @storybook/lit
gaetanmaisse Apr 26, 2021
009d137
Revert "refactor(builders): require react in the SB app context as it…
gaetanmaisse Apr 26, 2021
a0fe29a
example(lit): add stories for Addon Actions
gaetanmaisse Apr 26, 2021
211fda0
example(lit): add stories for Addon Background
gaetanmaisse Apr 26, 2021
58b9df6
example(lit): add stories for Addon Viewport
gaetanmaisse Apr 29, 2021
5ec74ec
example(lit): add stories for Addon Toolbars
gaetanmaisse May 4, 2021
5d1a395
feat(lit): bootstrap support of Lit in Addon Docs
gaetanmaisse May 4, 2021
68b9c1e
example(lit): add basic stories for Addon Docs
gaetanmaisse May 4, 2021
95961b2
example(lit): add stories for Addon Controls and improve "demo button"
gaetanmaisse May 4, 2021
a763df2
Merge branch 'next' into @storybook/lit
gaetanmaisse May 4, 2021
0a40da0
refactor(docs): extract prepareForInline and fix to TS errors
gaetanmaisse May 4, 2021
16062a0
example(lit): remove stories for deprecated features `info` and `note`
gaetanmaisse May 4, 2021
c1ee5ad
example(lit): filter `lit-kitchen-sink` from `yarn build-storybooks` …
gaetanmaisse May 5, 2021
e43a50c
Merge branch 'next' into pr/14600
shilman May 10, 2021
fa82eca
feat(lit): fix Deepscan warning and strengthen TypeScript compilation…
gaetanmaisse May 10, 2021
3cc3da4
example(lit): remove unused addons from dependencies
gaetanmaisse May 10, 2021
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -40,4 +40,4 @@ examples/angular-cli/addon-jest.testresults.json
!/.yarn/plugins
!/.yarn/sdks
!/.yarn/versions
/.pnp.*
.pnp.*
7 changes: 4 additions & 3 deletions addons/docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -103,10 +103,10 @@ First add the package. Make sure that the versions for your `@storybook/*` packa
yarn add -D @storybook/addon-docs
```

Docs has peer dependencies on `react` and `babel-loader`. If you want to write stories in MDX, you may need to add these dependencies as well:
Docs has peer dependencies on `react`. If you want to write stories in MDX, you may need to add this dependency as well:

```sh
yarn add -D react babel-loader
yarn add -D react
```

Then add the following to your `.storybook/main.js`:
Expand Down Expand Up @@ -183,7 +183,8 @@ module.exports = {
test: /\.(stories|story)\.mdx$/,
use: [
{
loader: 'babel-loader',
// Need to add babel-loader as dependency: `yarn add -D babel-loader`
loader: require.resolve('babel-loader'),
// may or may not need this line depending on your app's setup
options: {
plugins: ['@babel/plugin-transform-react-jsx'],
Expand Down
4 changes: 2 additions & 2 deletions addons/docs/angular/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -96,10 +96,10 @@ storiesOf('App Component', module)

[MDX](../docs/mdx.md) is a convenient way to document your components in Markdown and embed documentation components, such as stories and props tables, inline.

Docs has peer dependencies on `react` and `babel-loader`. If you want to write stories in MDX, you'll need to add these dependencies as well:
Docs has peer dependencies on `react`. If you want to write stories in MDX, you may need to add this dependency as well:

```sh
yarn add -D react babel-loader
yarn add -D react
```

Then update your `.storybook/main.js` to make sure you load MDX files:
Expand Down
4 changes: 2 additions & 2 deletions addons/docs/common/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,10 @@ When you [install docs](#installation) you should get basic [DocsPage](../docs/d

[MDX](../docs/mdx.md) is a convenient way to document your components in Markdown and embed documentation components, such as stories and props tables, inline.

Docs has peer dependencies on `react` and `babel-loader`. If you want to write stories in MDX, you'll need to add these dependencies as well:
Docs has peer dependencies on `react`. If you want to write stories in MDX, you may need to add this dependency as well:

```sh
yarn add -D react babel-loader
yarn add -D react
```

Then update your `.storybook/main.js` to make sure you load MDX files:
Expand Down
4 changes: 2 additions & 2 deletions addons/docs/ember/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,10 +78,10 @@ storiesOf('App Component', module)

[MDX](../docs/mdx.md) is a convenient way to document your components in Markdown and embed documentation components, such as stories and props tables, inline.

Docs has peer dependencies on `react` and `babel-loader`. If you want to write stories in MDX, you'll need to add these dependencies as well:
Docs has peer dependencies on `react`. If you want to write stories in MDX, you may need to add this dependency as well:

```sh
yarn add -D react babel-loader
yarn add -D react
```

Then update your `.storybook/main.js` to make sure you load MDX files:
Expand Down
2 changes: 0 additions & 2 deletions addons/docs/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -130,12 +130,10 @@
"zone.js": "^0.11.3"
},
"peerDependencies": {
"@babel/core": "^7.11.5",
"@storybook/angular": "6.3.0-alpha.8",
"@storybook/vue": "6.3.0-alpha.8",
"@storybook/vue3": "6.3.0-alpha.8",
"@storybook/web-components": "6.3.0-alpha.8",
"babel-loader": "^8.0.0",
"lit-html": "^1.0.0",
"react": "^16.8.0 || ^17.0.0",
"react-dom": "^16.8.0 || ^17.0.0",
Expand Down
6 changes: 0 additions & 6 deletions addons/docs/react/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,12 +67,6 @@ storiesOf('InfoButton', module)

[MDX](../docs/mdx.md) is a convenient way to document your components in Markdown and embed documentation components, such as stories and props tables, inline.

Docs has peer dependencies on `react` and `babel-loader`. If you want to write stories in MDX, you may need to add these dependencies as well:

```sh
yarn add -D react babel-loader
```

Then update your `.storybook/main.js` to make sure you load MDX files:

```js
Expand Down
4 changes: 2 additions & 2 deletions addons/docs/vue/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -93,10 +93,10 @@ storiesOf('InfoButton', module)

[MDX](../docs/mdx.md) is a convenient way to document your components in Markdown and embed documentation components, such as stories and props tables, inline.

Docs has peer dependencies on `react` and `babel-loader`. If you want to write stories in MDX, you'll need to add these dependencies as well:
Docs has peer dependencies on `react`. If you want to write stories in MDX, you may need to add this dependency as well:

```sh
yarn add -D react babel-loader
yarn add -D react
```

Then update your `.storybook/main.js` to make sure you load MDX files:
Expand Down
4 changes: 2 additions & 2 deletions addons/docs/vue3/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -93,10 +93,10 @@ storiesOf('InfoButton', module)

[MDX](../docs/mdx.md) is a convenient way to document your components in Markdown and embed documentation components, such as stories and props tables, inline.

Docs has peer dependencies on `react` and `babel-loader`. If you want to write stories in MDX, you'll need to add these dependencies as well:
Docs has peer dependencies on `react`. If you want to write stories in MDX, you may need to add this dependency as well:

```sh
yarn add -D react babel-loader
yarn add -D react
```

Then update your `.storybook/main.js` to make sure you load MDX files:
Expand Down
6 changes: 6 additions & 0 deletions app/lit/.eslintrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
module.exports = {
extends: ['../../.eslintrc.js'],
rules: {
'import/extensions': 0,
},
};
76 changes: 76 additions & 0 deletions app/lit/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
⚠️️

⚠️️ @storybook/lit is currently experimental and everything related to it is subject to breaking changes at any time. Please DO NOT use it in real projects.

⚠️

# Storybook for lit

---

Storybook for lit is a UI development environment for your lit 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/master/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

⚠️️ NOT WORKING FOR NOW
npx -p @storybook/cli sb init -t lit
```

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

---

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

# 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

module.exports = {
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>
4 changes: 4 additions & 0 deletions app/lit/bin/build.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#!/usr/bin/env node

process.env.NODE_ENV = process.env.NODE_ENV || 'production';
require('../dist/cjs/server/build');
3 changes: 3 additions & 0 deletions app/lit/bin/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#!/usr/bin/env node

require('../dist/cjs/server');
73 changes: 73 additions & 0 deletions app/lit/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
{
"name": "@storybook/lit",
"version": "6.3.0-alpha.8",
"description": "Storybook for lit: View web components snippets in isolation with Hot Reloading.",
"keywords": [
"lit",
"lit-element",
"lit-html",
"storybook",
"web-components"
],
"homepage": "https://github.com/storybookjs/storybook/tree/master/app/lit",
"bugs": {
"url": "https://github.com/storybookjs/storybook/issues"
},
"repository": {
"type": "git",
"url": "https://github.com/storybookjs/storybook.git",
"directory": "app/lit"
},
"license": "MIT",
"main": "dist/cjs/client/index.js",
"module": "dist/esm/client/index.js",
"types": "dist/ts3.9/client/index.d.ts",
"typesVersions": {
"<3.8": {
"*": [
"dist/ts3.4/*"
]
}
},
"bin": {
"build-storybook": "./bin/build.js",
"start-storybook": "./bin/index.js",
"storybook-server": "./bin/index.js"
},
"files": [
"bin/**/*",
"dist/**/*",
"README.md",
"*.js",
"*.d.ts"
],
"scripts": {
"prepare": "node ../../scripts/prepare.js"
},
"dependencies": {
"@storybook/addons": "6.3.0-alpha.8",
"@storybook/client-api": "6.3.0-alpha.8",
"@storybook/core": "6.3.0-alpha.8",
"@storybook/core-common": "6.3.0-alpha.8",
"@types/webpack-env": "^1.16.0",
"core-js": "^3.8.2",
"global": "^4.4.0",
"react": "16.14.0",
"react-dom": "16.14.0",
"read-pkg-up": "^7.0.1",
"ts-dedent": "^2.0.0"
},
"devDependencies": {
"@types/webpack": "^4.41.26",
"lit": "^2.0.0-pre.2"
},
"peerDependencies": {
"lit": "^2.0.0-pre.2"
},
"engines": {
"node": ">=12"
},
"publishConfig": {
"access": "public"
}
}
32 changes: 32 additions & 0 deletions app/lit/src/client/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { EventSource, window } from 'global';

export {
storiesOf,
setAddon,
addDecorator,
addParameters,
configure,
getStorybook,
forceReRender,
raw,
} from './preview';

export * from './preview/types';

// TODO: disable HMR and do full page loads because of customElements.define
if (module && module.hot && module.hot.decline) {
module.hot.decline();
// forcing full reloads for customElements as elements can only be defined once per page
const hmr = new EventSource('__webpack_hmr');
hmr.addEventListener('message', function fullPageReload(event: { data: string }) {
try {
// Only care for built events. Heartbeats are not parsable so we ignore those
const { action } = JSON.parse(event.data);
if (action === 'built') {
window.location.reload();
}
} catch (error) {
// Most part we only get here from the data in the server-sent event not being parsable which is ok
}
});
}
3 changes: 3 additions & 0 deletions app/lit/src/client/preview/globals.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import { window } from 'global';

window.STORYBOOK_ENV = 'lit';
37 changes: 37 additions & 0 deletions app/lit/src/client/preview/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/* eslint-disable prefer-destructuring */
import { start } from '@storybook/core/client';
import { ClientStoryApi, Loadable } from '@storybook/addons';

import './globals';
import render from './render';
import { StoryFnLitReturnType, IStorybookSection } from './types';

const framework = 'lit';

interface ClientApi extends ClientStoryApi<StoryFnLitReturnType> {
setAddon(addon: any): void;
configure(loader: Loadable, module: NodeModule): void;
getStorybook(): IStorybookSection[];
clearDecorators(): void;
forceReRender(): void;
raw: () => any; // todo add type
}

const api = start(render);

export const storiesOf: ClientApi['storiesOf'] = (kind, m) => {
return (api.clientApi.storiesOf(kind, m) as ReturnType<ClientApi['storiesOf']>).addParameters({
framework,
});
};

export const configure: ClientApi['configure'] = (...args) => api.configure(framework, ...args);
export const addDecorator: ClientApi['addDecorator'] = api.clientApi
.addDecorator as ClientApi['addDecorator'];
export const addParameters: ClientApi['addParameters'] = api.clientApi
.addParameters as ClientApi['addParameters'];
export const clearDecorators: ClientApi['clearDecorators'] = api.clientApi.clearDecorators;
export const setAddon: ClientApi['setAddon'] = api.clientApi.setAddon;
export const forceReRender: ClientApi['forceReRender'] = api.forceReRender;
export const getStorybook: ClientApi['getStorybook'] = api.clientApi.getStorybook;
export const raw: ClientApi['raw'] = api.clientApi.raw;
33 changes: 33 additions & 0 deletions app/lit/src/client/preview/render.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { document, Node } from 'global';
import dedent from 'ts-dedent';
import { render } from 'lit';
import { isTemplateResult } from 'lit/directive-helpers.js';
// import { simulatePageLoad, simulateDOMContentLoaded } from '@storybook/client-api';
import { RenderContext } from './types';

const rootElement = document.getElementById('root');

export default function renderMain({
storyFn,
kind,
name,
showMain,
showError,
forceRender,
}: RenderContext) {
const element = storyFn();

showMain();

if (isTemplateResult(element)) {
render(element, rootElement);
} else {
showError({
title: `Expecting an lit template result from the story: "${name}" of "${kind}".`,
description: dedent`
Did you forget to return the lit template result from the story?
Use "() => html\`<your snippet or node>\`" or when defining the story.
`,
});
}
}