Merge branch 'next' into pr/Diokuz/7824

# Conflicts:
#	addons/contexts/package.json
This commit is contained in:
Norbert de Langen 2019-09-23 19:35:58 +02:00
commit 263e56be4e
283 changed files with 3481 additions and 2582 deletions

10
.github/CODEOWNERS vendored
View File

@ -7,12 +7,12 @@
/addons/centered/ @kazupon
/addons/events/ @z4o4z @ndelangen
/addons/graphql/ @mnmtanish
/addons/info/ @theinterned @z4o4z @UsulPro @dangreenisrael @danielduan
/addons/info/ @theinterned @z4o4z @UsulPro @dangreenisrael
/addons/jest/ @renaudtertrais
/addons/knobs/ @alexandrebodin @theinterned @leonrodenburg @alterx
/addons/links/ @ndelangen
/addons/notes/ @alexandrebodin
/addons/options/ @danielduan @UsulPro
/addons/options/ @UsulPro
/addons/storyshots/ @igor-dv @thomasbertet
/addons/storysource/ @igor-dv
/addons/viewport/ @saponifi3d
@ -20,7 +20,7 @@
/app/angular/ @alterx @igor-dv
/app/polymer/ @ndelangen @naipath @leonrodenburg
/app/react/ @xavcz @shilman @thomasbertet
/app/react-native/ @rmevans9 @danielduan @Gongreg @tmeasday
/app/react-native/ @rmevans9 @Gongreg @tmeasday
/app/vue/ @thomasbertet @kazupon
/app/svelte/ @plumpNation
@ -29,12 +29,12 @@
/examples/angular-cli/ @igor-dv @alterx
/examples/cra-kitchen-sink/ @ndelangen @UsulPro
/examples/cra-ts-kitchen-sink/ @mucsi96
/examples/official-storybook/ @danielduan @UsulPro
/examples/official-storybook/ @UsulPro
/examples/polymer-cli/ @naipath @igor-dv
/examples/vue-kitchen-sink/ @igor-dv @alexandrebodin
/examples/svelte-kitchen-sink/ @plumpNation
/examples-native/crna-kitchen-sink/ @Gongreg @danielduan
/examples-native/crna-kitchen-sink/ @Gongreg
/lib/addons/ @ndelangen @theinterned
/lib/channel-postmessage/ @mnmtanish @ndelangen

32
.github/main.workflow vendored
View File

@ -1,32 +0,0 @@
action "Danger JS" {
uses = "danger/danger-js@master"
secrets = ["GITHUB_TOKEN"]
args = "--dangerfile .ci/danger/dangerfile.ts"
}
workflow "Dangerfile JS Pull" {
on = "pull_request"
resolves = "Danger JS"
}
workflow "Dangerfile JS Label" {
on = "label"
resolves = "Danger JS"
}
# ===
action "Automention" {
uses = "shilman/automention@master"
secrets = ["GITHUB_TOKEN"]
}
workflow "Automention Issues" {
on = "issues"
resolves = "Automention"
}
workflow "Automention PRs" {
on = "pull_request"
resolves = "Automention"
}

12
.github/workflows/issues.yml vendored Normal file
View File

@ -0,0 +1,12 @@
on: issues
name: Automention Issues
jobs:
automention:
name: Automention
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@master
- name: Automention
uses: shilman/automention@master
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

14
.github/workflows/label.yml vendored Normal file
View File

@ -0,0 +1,14 @@
on: label
name: Dangerfile JS Label
jobs:
dangerJS:
name: Danger JS
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@master
- name: Danger JS
uses: danger/danger-js@master
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
args: --dangerfile .ci/danger/dangerfile.ts

View File

@ -1,4 +1,4 @@
name: Node CI
name: Github CI
on: [push]
@ -9,8 +9,8 @@ jobs:
runs-on: ${{ matrix.os }}
strategy:
matrix:
node-version: [8, 10, 12]
os: [ubuntu-latest, windows-latest, macOS-latest]
node-version: [10]
os: [ubuntu-latest]
steps:
- uses: actions/checkout@v1

View File

@ -0,0 +1,12 @@
on: pull_request
name: Automention PRs
jobs:
automention:
name: Automention
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@master
- name: Automention
uses: shilman/automention@master
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

View File

@ -0,0 +1,14 @@
on: pull_request
name: Dangerfile JS Pull
jobs:
dangerJS:
name: Danger JS
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@master
- name: Danger JS
uses: danger/danger-js@master
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
args: --dangerfile .ci/danger/dangerfile.ts

3
.gitignore vendored
View File

@ -30,4 +30,5 @@ scripts/storage
htpasswd
/false
storybook-out
/addons/docs/common/config-*
/addons/docs/common/config-*
built-storybooks

View File

@ -1,3 +1,235 @@
## 5.2.1 (September 17, 2019)
### Bug Fixes
* Core: Fix error handling ([#8097](https://github.com/storybookjs/storybook/pull/8097))
## 5.3.0-alpha.0 (September 16, 2019)
### Features
* UI: Debounce sidebar search filter ([#8032](https://github.com/storybookjs/storybook/pull/8032))
### Bug Fixes
* Core: Fix error handling ([#8097](https://github.com/storybookjs/storybook/pull/8097))
### Maintenance
* CLI: Add wrapper packages: sb & storybook ([#8034](https://github.com/storybookjs/storybook/pull/8034))
* Build: Update now config ([#8049](https://github.com/storybookjs/storybook/pull/8049))
## 5.2.0 (September 13, 2019)
Storybook 5.2 is here!
- 📚 DocsPage: Zero-config documentation
- 📦 Component Story Format: Portable ES6 modules
- 🖼 Design System: Best practice component development
- 🧩 Addon API: Simplified w/ hooks
5.2 contains hundreds more fixes, features, and tweaks. Browse the changelogs matching `5.2.0-alpha.*`, `5.2.0-beta.*`, and `5.2.0-rc.*` for the full list of changes. See [MIGRATION.md](https://github.com/storybookjs/storybook/blob/next/MIGRATION.md) to upgrade from `5.0` or earlier.
## 5.2.0-rc.11 (September 10, 2019)
### Features
* DocsPage: show docs.storyDescription above story ([#8037](https://github.com/storybookjs/storybook/pull/8037))
### Maintenance
* Migrate to new github actions ([#8045](https://github.com/storybookjs/storybook/pull/8045))
## 5.2.0-rc.10 (September 9, 2019)
### Bug Fixes
* Angular: remove webpack-env from tsconfig types ([#8036](https://github.com/storybookjs/storybook/pull/8036))
### Documentation
* Guides: Update all guides to CSF ([#8030](https://github.com/storybookjs/storybook/pull/8030))
## 5.2.0-rc.9 (September 7, 2019)
### Bug Fixes
* Addon-knobs: allow array values in select and options knobs ([#8027](https://github.com/storybookjs/storybook/pull/8027))
## 5.2.0-rc.8 (September 6, 2019)
### Bug Fixes
* Addon-docs: Scroll story into view ([#7994](https://github.com/storybookjs/storybook/pull/7994))
* Addon-docs: Fix LI styling for dark color theme ([#8015](https://github.com/storybookjs/storybook/pull/8015))
## 5.2.0-rc.7 (September 6, 2019)
Publish failed
## 5.2.0-rc.6 (September 5, 2019)
### Bug Fixes
* Addon-docs: Doc blocks fixes for dark theme ([#7991](https://github.com/storybookjs/storybook/pull/7991))
* API: Fix useEfect in inline Docs ([#7992](https://github.com/storybookjs/storybook/pull/7992))
* UI: Fix enableShortcuts option ([#7990](https://github.com/storybookjs/storybook/pull/7990))
* Addon-docs: Error handling for invalid Story id ([#7965](https://github.com/storybookjs/storybook/pull/7965))
## 5.2.0-rc.5 (September 4, 2019)
### Bug Fixes
* CLI: Force welcome stories to show up first in load order ([#7979](https://github.com/storybookjs/storybook/pull/7979))
## 5.2.0-rc.4 (September 3, 2019)
### Bug Fixes
* Addon-docs: Fix MDX theme bleed with reset context ([#7974](https://github.com/storybookjs/storybook/pull/7974))
## 5.2.0-rc.3 (September 3, 2019)
Failed publish
## 5.2.0-rc.2 (September 1, 2019)
### Bug Fixes
* Addon-docs: Fix inline stories using react hooks ([#7946](https://github.com/storybookjs/storybook/pull/7946))
## 5.2.0-rc.1 (August 31, 2019)
### Features
* Core: Add html lang attribute to iframe ([#7892](https://github.com/storybookjs/storybook/pull/7892))
### Bug Fixes
* Source-loader: Fix CSF display name handling ([#7940](https://github.com/storybookjs/storybook/pull/7940))
* React-native: Resolve deprecated methods ([#7908](https://github.com/storybookjs/storybook/pull/7908))
* Addon-viewport: keep styles on rotation-change ([#7683](https://github.com/storybookjs/storybook/pull/7683))
* Addon-viewport: Fix defaultViewport ([#7934](https://github.com/storybookjs/storybook/pull/7934))
## 5.2.0-rc.0 (August 30, 2019)
5.2 is in RC!!! 🎉What this means:
- no glaring bugs relating to new features (that we know of)
- bugfixes only until 5.2 final
- follow-on features to be released in `5.3-alpha` ASAP
Track progress on the [5.2 release issue](https://github.com/storybookjs/storybook/issues/7430)
## 5.2.0-beta.48 (August 30, 2019)
### Bug Fixes
* Addon-docs: Fix docs-only story ID suffix ([#7921](https://github.com/storybookjs/storybook/pull/7921))
### Maintenance
* Replace favicon with new Storybook icon. ([#7922](https://github.com/storybookjs/storybook/pull/7922))
### Dependency Upgrades
* Bump react-draggable from 3.1.1 to 3.3.2 ([#7912](https://github.com/storybookjs/storybook/pull/7912))
## 5.2.0-beta.47 (August 30, 2019)
### Bug Fixes
* UI: Optimize treeview render/filter performance ([#7910](https://github.com/storybookjs/storybook/pull/7910))
* Addon-docs: Fix DocsPage to respect displayName ([#7915](https://github.com/storybookjs/storybook/pull/7915))
## 5.2.0-beta.46 (August 29, 2019)
CSF users: this reverts the `makeDisplayName` change introduced in `5.2.0-beta.43` for maintainability reasons. See [#7901](https://github.com/storybookjs/storybook/pull/7901) for full rationale. And apologies for the inconvenience!
### Bug Fixes
* React: Fix missing props in the Welcome.tsx demo ([#7774](https://github.com/storybookjs/storybook/pull/7774))
### Maintenance
* CSF: Revert `makeDisplayName` & add stable `storyNameFromExport` ([#7901](https://github.com/storybookjs/storybook/pull/7901))
* Addon-a11y: Upgrade axe to 3.3.2 which adds/mods rules ([#7888](https://github.com/storybookjs/storybook/pull/7888))
## 5.2.0-beta.45 (August 28, 2019)
### Bug Fixes
* Addon-docs: Fix MDX Story ID to match new CSF ([#7894](https://github.com/storybookjs/storybook/pull/7894))
## 5.2.0-beta.44 (August 28, 2019)
Publish failed
## 5.2.0-beta.43 (August 28, 2019)
CSF users: This is potentially a breaking change. If you want to opt-out of the new default display name calculation (`lodash.startCase`) you can add the following to your SB config:
```js
addParameters({ options: { makeDisplayName: key => key }});
```
### Features
* CSF: Transform CSF named exports w/ `makeDisplayName` ([#7878](https://github.com/storybookjs/storybook/pull/7878))
## 5.2.0-beta.42 (August 28, 2019)
Addon-docs users: This is a breaking change if you have been hacking the `docs` parameter manually. If you're using the zero-config option for `DocsPage` or `MDX`, you should be unaffected by it.
### Maintenance
* Addon-docs: Make config API consistent with other addons ([#7874](https://github.com/storybookjs/storybook/pull/7874))
## 5.2.0-beta.41 (August 27, 2019)
### Features
* Addon-info: Add configurable component comparator ([#7409](https://github.com/storybookjs/storybook/pull/7409))
### Bug Fixes
* Addon-viewports: Add back default viewports ([#7448](https://github.com/storybookjs/storybook/pull/7448))
* Core: Pass a separate hooks context per story ([#7860](https://github.com/storybookjs/storybook/pull/7860))
* UI: Fix TooltipLinkList not scrollable ([#7865](https://github.com/storybookjs/storybook/pull/7865))
### Maintenance
* UI: Add ignore `first-child` selector warning flag ([#7861](https://github.com/storybookjs/storybook/pull/7861))
## 5.2.0-beta.40 (August 23, 2019)
### Bug Fixes
* Addon-docs: Fix DocsPage primary story switching ([#7849](https://github.com/storybookjs/storybook/pull/7849))
* Source-loader: Selectively ignore typescript errors in generated code ([#7845](https://github.com/storybookjs/storybook/pull/7845))
* Addon-docs: Force hidden attribute on #root element ([#7841](https://github.com/storybookjs/storybook/pull/7841))
### Maintenance
* Remove temporarily added --no-dll option on examples ([#7647](https://github.com/storybookjs/storybook/pull/7647))
## 5.2.0-beta.39 (August 22, 2019)
### Bug Fixes
* React-Native: Fix tabs layout issue on simulator ([#7809](https://github.com/storybookjs/storybook/pull/7809))
* Source-loader: Selectively ignore typescript errors in generated code ([#7831](https://github.com/storybookjs/storybook/pull/7831))
## 5.2.0-beta.38 (August 21, 2019)
### Bug Fixes
* FIX issue where the block of build info (including url) wouldn't show if passed --ci #7821 ([#7822](https://github.com/storybookjs/storybook/pull/7822))
### Maintenance
* CLI: Remove babel-register in favor of esm ([#7823](https://github.com/storybookjs/storybook/pull/7823))
## 5.2.0-beta.37 (August 20, 2019)
### Breaking Changes
@ -809,7 +1041,7 @@ Storybook 5.1 is a juicy upgrade including:
- 🛠 Context addon: New UI for themes, internationalization, & more
- 🎛 Presets: One-line configuration for babel, webpack, & addons
5.1 contains hundreds more fixes, features, and tweaks. Browse the changelogs matching `5.1.0-alpha.*`, `5.1.0-beta.*`, and `5.1.0-rc.*` for the full list of changes. See [MIGRATION.md](https://github.com/storybookjs/storybook/blob/next/MIGRATION.md) to ugprade from `5.0` or earlier.
5.1 contains hundreds more fixes, features, and tweaks. Browse the changelogs matching `5.1.0-alpha.*`, `5.1.0-beta.*`, and `5.1.0-rc.*` for the full list of changes. See [MIGRATION.md](https://github.com/storybookjs/storybook/blob/next/MIGRATION.md) to upgrade from `5.0` or earlier.
## 5.1.0 (June 5, 2019)
@ -1901,7 +2133,7 @@ Storybook 5.0 is a completely new UI with the following improvements:
- ⌨️ Improved keyboard shortcuts that are user configurable
- 🌍 New URL structure that eliminates long strings of query parameters
5.0 contains hundreds more fixes, features, and tweaks. Browse the changelogs matching `5.0.0-alpha.*`, `5.0.0-beta.*`, and `5.0.0-rc.*` for the full list of changes. See [MIGRATION.md](https://github.com/storybookjs/storybook/blob/next/MIGRATION.md) to ugprade from `4.x`.
5.0 contains hundreds more fixes, features, and tweaks. Browse the changelogs matching `5.0.0-alpha.*`, `5.0.0-beta.*`, and `5.0.0-rc.*` for the full list of changes. See [MIGRATION.md](https://github.com/storybookjs/storybook/blob/next/MIGRATION.md) to upgrade from `4.x`.
## 5.0.0-rc.11 (March 5, 2019)

View File

@ -67,6 +67,21 @@
## From version 5.1.x to 5.2.x
### default viewports
The default viewports have been reduced to a smaller set, we think is enough for most usecases.
You can get the old default back by adding the following to your `config.js`:
```js
import { INITIAL_VIEWPORTS } from '@storybook/addon-viewport';
addParameters({
viewport: {
viewports: INITIAL_VIEWPORTS,
},
});
```
### Grid toolbar-feature
The grid feature in the toolbar has been relocated to [addon-background](https://github.com/storybookjs/storybook/tree/next/addons/backgrounds), follow the setup intructions on that addon to get the feature again.

View File

@ -1,38 +1,62 @@
# Storybook
<p align="center">
<a href="https://circleci.com/gh/storybookjs/storybook"><img src="https://circleci.com/gh/storybookjs/storybook.svg?style=shield" alt="Build Status on CircleCI" /></a>
<a href="https://www.codefactor.io/repository/github/storybookjs/storybook"><img src="https://www.codefactor.io/repository/github/storybookjs/storybook/badge" alt="CodeFactor" /></a>
<a href="https://snyk.io/test/github/storybookjs/storybook"><img src="https://snyk.io/test/github/storybookjs/storybook/badge.svg" alt="Known Vulnerabilities" /></a>
<a href="https://bettercodehub.com/results/storybookjs/storybook"><img src="https://bettercodehub.com/edge/badge/storybookjs/storybook" alt="BCH compliance" /></a>
<a href="https://codecov.io/gh/storybookjs/storybook"><img src="https://codecov.io/gh/storybookjs/storybook/branch/master/graph/badge.svg" alt="codecov" /></a>
<a href="https://github.com/storybookjs/storybook/blob/master/LICENSE"><img src="https://img.shields.io/github/license/storybookjs/storybook.svg" alt="License" /></a></p>
</p>
<p align="center">
<a href="https://discord.gg/sMFvFsG"><img src="https://img.shields.io/badge/discord-join-7289DA.svg?logo=discord&longCache=true&style=flat" /></a>
<a href="https://now-examples-slackin-rrirkqohko.now.sh/"><img src="https://now-examples-slackin-rrirkqohko.now.sh/badge.svg?logo=slack" alt="Storybook Slack" /></a>
<a href="#backers"><img src="https://opencollective.com/storybook/backers/badge.svg" alt="Backers on Open Collective" /></a>
<a href="#sponsors"><img src="https://opencollective.com/storybook/sponsors/badge.svg" alt="Sponsors on Open Collective" /></a>
<a href="https://twitter.com/intent/follow?screen_name=storybookjs"><img src="https://img.shields.io/twitter/follow/storybookjs.svg?style=social&label=Follow" alt="Official Twitter Handle" /></a>
<a href="https://storybook.js.org/">
<img src="https://user-images.githubusercontent.com/321738/63501763-88dbf600-c4cc-11e9-96cd-94adadc2fd72.png" alt="Storybook" width="400" />
</a>
</p>
---
<p align="center">Build bulletproof UI components faster</p>
<br/>
<p align="center">
<a href="https://circleci.com/gh/storybookjs/storybook">
<img src="https://circleci.com/gh/storybookjs/storybook.svg?style=shield" alt="Build Status on CircleCI" />
</a>
<a href="https://www.codefactor.io/repository/github/storybookjs/storybook">
<img src="https://www.codefactor.io/repository/github/storybookjs/storybook/badge" alt="CodeFactor" />
</a>
<a href="https://snyk.io/test/github/storybookjs/storybook">
<img src="https://snyk.io/test/github/storybookjs/storybook/badge.svg" alt="Known Vulnerabilities" />
</a>
<a href="https://codecov.io/gh/storybookjs/storybook">
<img src="https://codecov.io/gh/storybookjs/storybook/branch/master/graph/badge.svg" alt="codecov" />
</a>
<a href="https://github.com/storybookjs/storybook/blob/master/LICENSE">
<img src="https://img.shields.io/github/license/storybookjs/storybook.svg" alt="License" />
</a>
<br/>
<a href="https://discord.gg/sMFvFsG">
<img src="https://img.shields.io/badge/discord-join-7289DA.svg?logo=discord&longCache=true&style=flat" />
</a>
<a href="https://now-examples-slackin-rrirkqohko.now.sh/">
<img src="https://now-examples-slackin-rrirkqohko.now.sh/badge.svg?logo=slack" alt="Storybook Slack" />
</a>
<a href="#backers">
<img src="https://opencollective.com/storybook/backers/badge.svg" alt="Backers on Open Collective" />
</a>
<a href="#sponsors">
<img src="https://opencollective.com/storybook/sponsors/badge.svg" alt="Sponsors on Open Collective" />
</a>
<a href="https://twitter.com/intent/follow?screen_name=storybookjs">
<img src="https://badgen.net/twitter/follow/storybookjs?icon=twitter&label=%40storybookjs" alt="Official Twitter Handle" />
</a>
</p>
Storybook is a development environment for UI components.
It allows you to browse a component library, view the different states of each component, and interactively develop and test components.
## Intro
<center>
<img src="media/storybook-intro.gif" width="100%" />
</center>
<p align="center">
README for:<br/>
View README for:<br/>
<a href="https://github.com/storybookjs/storybook/blob/master/README.md" title="latest"><img alt="latest" src="https://img.shields.io/npm/v/@storybook/core/latest.svg" /></a>
<a href="https://github.com/storybookjs/storybook/blob/next/README.md" title="next"><img alt="next" src="https://img.shields.io/npm/v/@storybook/core/next.svg" /></a>
</p>
## Intro
Storybook runs outside of your app. This allows you to develop UI components in isolation, which can improve component reuse, testability, and development speed. You can build quickly without having to worry about application-specific dependencies.
Here are some featured examples that you can reference to see how Storybook works: <https://storybook.js.org/examples/>

View File

@ -45,7 +45,7 @@ storiesOf('button', module)
```
For more customizability. Use the `addParameters` function to configure [aXe options](https://github.com/dequelabs/axe-core/blob/develop/doc/API.md#api-name-axeconfigure).
You can override these options at story level too.
You can override these options [at story level too](https://storybook.js.org/docs/configurations/options-parameter/#per-story-options).
```js
import React from 'react';

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/addon-a11y",
"version": "5.2.0-beta.37",
"version": "5.3.0-alpha.0",
"description": "a11y addon for storybook",
"keywords": [
"a11y",
@ -32,13 +32,13 @@
"prepare": "node ../../scripts/prepare.js"
},
"dependencies": {
"@storybook/addons": "5.2.0-beta.37",
"@storybook/api": "5.2.0-beta.37",
"@storybook/client-logger": "5.2.0-beta.37",
"@storybook/components": "5.2.0-beta.37",
"@storybook/core-events": "5.2.0-beta.37",
"@storybook/theming": "5.2.0-beta.37",
"axe-core": "^3.2.2",
"@storybook/addons": "5.3.0-alpha.0",
"@storybook/api": "5.3.0-alpha.0",
"@storybook/client-logger": "5.3.0-alpha.0",
"@storybook/components": "5.3.0-alpha.0",
"@storybook/core-events": "5.3.0-alpha.0",
"@storybook/theming": "5.3.0-alpha.0",
"axe-core": "^3.3.2",
"common-tags": "^1.8.0",
"core-js": "^3.0.1",
"global": "^4.3.2",

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/addon-actions",
"version": "5.2.0-beta.37",
"version": "5.3.0-alpha.0",
"description": "Action Logger addon for storybook",
"keywords": [
"storybook"
@ -27,12 +27,12 @@
"prepare": "node ../../scripts/prepare.js"
},
"dependencies": {
"@storybook/addons": "5.2.0-beta.37",
"@storybook/api": "5.2.0-beta.37",
"@storybook/client-api": "5.2.0-beta.37",
"@storybook/components": "5.2.0-beta.37",
"@storybook/core-events": "5.2.0-beta.37",
"@storybook/theming": "5.2.0-beta.37",
"@storybook/addons": "5.3.0-alpha.0",
"@storybook/api": "5.3.0-alpha.0",
"@storybook/client-api": "5.3.0-alpha.0",
"@storybook/components": "5.3.0-alpha.0",
"@storybook/core-events": "5.3.0-alpha.0",
"@storybook/theming": "5.3.0-alpha.0",
"core-js": "^3.0.1",
"fast-deep-equal": "^2.0.1",
"global": "^4.3.2",

View File

@ -4,7 +4,7 @@ Storybook Background Addon can be used to change background colors inside the pr
[Framework Support](https://github.com/storybookjs/storybook/blob/master/ADDONS_SUPPORT.md)
![React Storybook Screenshot](https://storybook.js.org/img/addon-backgrounds.gif)
![React Storybook Screenshot](https://raw.githubusercontent.com/storybookjs/storybook/master/docs/static/img/addon-backgrounds.gif)
## Installation

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/addon-backgrounds",
"version": "5.2.0-beta.37",
"version": "5.3.0-alpha.0",
"description": "A storybook addon to show different backgrounds for your preview",
"keywords": [
"addon",
@ -31,12 +31,12 @@
"prepare": "node ../../scripts/prepare.js"
},
"dependencies": {
"@storybook/addons": "5.2.0-beta.37",
"@storybook/api": "5.2.0-beta.37",
"@storybook/client-logger": "5.2.0-beta.37",
"@storybook/components": "5.2.0-beta.37",
"@storybook/core-events": "5.2.0-beta.37",
"@storybook/theming": "5.2.0-beta.37",
"@storybook/addons": "5.3.0-alpha.0",
"@storybook/api": "5.3.0-alpha.0",
"@storybook/client-logger": "5.3.0-alpha.0",
"@storybook/components": "5.3.0-alpha.0",
"@storybook/core-events": "5.3.0-alpha.0",
"@storybook/theming": "5.3.0-alpha.0",
"core-js": "^3.0.1",
"memoizerific": "^1.11.3",
"react": "^16.8.3",

View File

@ -1,5 +1,6 @@
export const ADDON_ID = 'storybook/background';
export const PARAM_KEY = 'backgrounds';
export const GRID_PARAM_KEY = 'grid';
export const EVENTS = {
UPDATE: `${ADDON_ID}/update`,

View File

@ -128,7 +128,7 @@ export class BackgroundSelector extends Component<Props> {
<Global
styles={(theme: Theme) => ({
[`#${iframeId}`]: {
background:
backgroundColor:
selectedBackgroundColor === 'transparent'
? theme.background.content
: selectedBackgroundColor,

View File

@ -1,15 +1,20 @@
import React, { FunctionComponent } from 'react';
import React, { FunctionComponent, memo } from 'react';
import { useAddonState } from '@storybook/api';
import { useAddonState, useParameter } from '@storybook/api';
import { Global } from '@storybook/theming';
import { Icons, IconButton } from '@storybook/components';
import { ADDON_ID } from '../constants';
import { ADDON_ID, GRID_PARAM_KEY } from '../constants';
export interface BackgroundGridParameters {
cellSize: number;
}
const iframeId = 'storybook-preview-iframe';
export const GridSelector: FunctionComponent = () => {
export const GridSelector: FunctionComponent = memo(() => {
const [state, setState] = useAddonState<boolean>(`${ADDON_ID}/grid`);
const { cellSize } = useParameter<BackgroundGridParameters>(GRID_PARAM_KEY, { cellSize: 20 });
return (
<IconButton
@ -23,19 +28,24 @@ export const GridSelector: FunctionComponent = () => {
<Global
styles={{
[`#${iframeId}`]: {
backgroundSize: '100px 100px, 100px 100px, 20px 20px, 20px 20px',
backgroundSize: [
`${cellSize * 5}px ${cellSize * 5}px`,
`${cellSize * 5}px ${cellSize * 5}px`,
`${cellSize}px ${cellSize}px`,
`${cellSize}px ${cellSize}px`,
].join(', '),
backgroundPosition: '-1px -1px, -1px -1px, -1px -1px, -1px -1px',
backgroundBlendMode: 'difference',
backgroundImage: [
'linear-gradient(rgba(130, 130, 130,0.5) 1px,transparent 1px)',
'linear-gradient(90deg,rgb(130, 130, 130,0.5) 1px,transparent 1px)',
'linear-gradient(rgba(130, 130, 130, 0.25) 1px,transparent 1px)',
'linear-gradient(90deg,rgba(130, 130, 130, 0.25) 1px,transparent 1px)',
].join(','),
'linear-gradient(rgba(130, 130, 130, 0.5) 1px, transparent 1px)',
'linear-gradient(90deg, rgba(130, 130, 130, 0.5) 1px, transparent 1px)',
'linear-gradient(rgba(130, 130, 130, 0.25) 1px, transparent 1px)',
'linear-gradient(90deg, rgba(130, 130, 130, 0.25) 1px, transparent 1px)',
].join(', '),
},
}}
/>
) : null}
</IconButton>
);
};
});

View File

@ -4,6 +4,8 @@ Storybook Centered Decorator can be used to center components inside the preview
[Framework Support](https://github.com/storybookjs/storybook/blob/master/ADDONS_SUPPORT.md)
⚠️ This addon applies styling to the view in order to center the component. This may impact the look and feel of story.
### Usage
```sh

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/addon-centered",
"version": "5.2.0-beta.37",
"version": "5.3.0-alpha.0",
"description": "Storybook decorator to center components",
"keywords": [
"addon",
@ -37,7 +37,7 @@
"prepare": "node ../../scripts/prepare.js"
},
"dependencies": {
"@storybook/addons": "5.2.0-beta.37",
"@storybook/addons": "5.3.0-alpha.0",
"core-js": "^3.0.1",
"global": "^4.3.2",
"util-deprecate": "^1.0.2"
@ -47,13 +47,5 @@
"mithril": "*",
"preact": "*",
"react": "*"
},
"peerDependencies": {
"mithril": "*",
"preact": "*",
"react": "*"
},
"publishConfig": {
"access": "public"
}
}

View File

@ -1,4 +1,5 @@
/** @jsx m */
/* eslint-disable import/no-extraneous-dependencies */
import m, { ComponentTypes } from 'mithril';
import { makeDecorator } from '@storybook/addons';
import parameters from './parameters';

View File

@ -1,4 +1,5 @@
/** @jsx h */
/* eslint-disable import/no-extraneous-dependencies */
import { Component, h } from 'preact';
import { makeDecorator } from '@storybook/addons';
import parameters from './parameters';

View File

@ -1,9 +1,8 @@
/** @jsx createElement */
// eslint-disable-next-line import/no-extraneous-dependencies
/* eslint-disable import/no-extraneous-dependencies */
import { createElement } from 'rax';
// eslint-disable-next-line import/no-extraneous-dependencies
import View from 'rax-view';
import { makeDecorator } from '@storybook/addons/src/make-decorator';
import { makeDecorator } from '@storybook/addons';
import parameters from './parameters';
import styles from './styles';

View File

@ -1,3 +1,4 @@
/* eslint-disable import/no-extraneous-dependencies */
import React, { ReactNode } from 'react';
import { makeDecorator, StoryFn } from '@storybook/addons';
import parameters from './parameters';

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/addon-contexts",
"version": "5.2.0-beta.37",
"version": "5.3.0-alpha.0",
"description": "Storybook Addon Contexts",
"keywords": [
"preact",
@ -28,16 +28,13 @@
"prepare": "node ../../scripts/prepare.js"
},
"dependencies": {
"@storybook/addons": "5.2.0-beta.37",
"@storybook/api": "5.2.0-beta.37",
"@storybook/components": "5.2.0-beta.37",
"@storybook/core-events": "5.2.0-beta.37",
"core-js": "^3.0.1"
},
"devDependencies": {
"preact": "*",
"react": "*",
"vue": "*"
"@storybook/addons": "5.3.0-alpha.0",
"@storybook/api": "5.3.0-alpha.0",
"@storybook/components": "5.3.0-alpha.0",
"@storybook/core-events": "5.3.0-alpha.0",
"core-js": "^3.0.1",
"global": "^4.3.2",
"qs": "^6.6.0"
},
"peerDependencies": {
"global": "*",

View File

@ -1,5 +1,6 @@
/* eslint-disable import/no-extraneous-dependencies */
import React, { useEffect, useState, useCallback } from 'react';
import { useChannel } from './libs/useChannel';
import { useChannel } from '@storybook/api';
import { ToolBar } from './components/ToolBar';
import { deserialize, serialize } from '../shared/serializers';
import { PARAM, REBOOT_MANAGER, UPDATE_MANAGER, UPDATE_PREVIEW } from '../shared/constants';
@ -21,11 +22,13 @@ export const ContextsManager: ContextsManager = ({ api }) => {
);
// from preview
useChannel(UPDATE_MANAGER, newNodes => setNodes(newNodes || []), []);
const emit = useChannel({
[UPDATE_MANAGER]: newNodes => setNodes(newNodes || []),
});
// to preview
useEffect(() => api.emit(REBOOT_MANAGER), []);
useEffect(() => api.emit(UPDATE_PREVIEW, state), [state]);
useEffect(() => emit(REBOOT_MANAGER), []);
useEffect(() => emit(UPDATE_PREVIEW, state), [state]);
useEffect(() => api.setQueryParams({ [PARAM]: serialize(state) }), [state]);
return <ToolBar nodes={nodes} state={state || {}} setSelected={setSelected} />;

View File

@ -1,3 +1,4 @@
/* eslint-disable import/no-extraneous-dependencies */
import React, { ComponentProps } from 'react';
import { Separator } from '@storybook/components';
import { ToolBarControl } from './ToolBarControl';

View File

@ -1,3 +1,4 @@
/* eslint-disable import/no-extraneous-dependencies */
import React from 'react';
import { ToolBarMenu } from './ToolBarMenu';
import { OPT_OUT } from '../../shared/constants';

View File

@ -1,3 +1,4 @@
/* eslint-disable import/no-extraneous-dependencies */
import React, { ComponentProps } from 'react';
import { Icons, IconButton, WithTooltipPure, TabButton } from '@storybook/components';
import { ToolBarMenuOptions } from './ToolBarMenuOptions';

View File

@ -1,3 +1,4 @@
/* eslint-disable import/no-extraneous-dependencies */
import React from 'react';
import { TooltipLinkList } from '@storybook/components';
import { OPT_OUT } from '../../shared/constants';

View File

@ -1,19 +0,0 @@
import addons from '@storybook/addons';
import { useEffect } from 'react';
import { AnyFunctionReturns } from '../../shared/types.d';
/**
* The React hook version of Storybook Channel API.
*/
type UseChannel = (
event: string,
eventHandler: AnyFunctionReturns<void>,
input?: unknown[]
) => void;
export const useChannel: UseChannel = (event, eventHandler, inputs = []) =>
useEffect(() => {
const channel = addons.getChannel();
channel.on(event, eventHandler);
return () => channel.removeListener(event, eventHandler);
}, inputs);

View File

@ -1,3 +1,4 @@
/* eslint-disable import/no-extraneous-dependencies */
import Preact from 'preact';
import { createAddonDecorator, Render } from '../../index';
import { ContextsPreviewAPI } from '../ContextsPreviewAPI';

View File

@ -1,3 +1,4 @@
/* eslint-disable import/no-extraneous-dependencies */
import React from 'react';
import { createAddonDecorator, Render } from '../../index';
import { ContextsPreviewAPI } from '../ContextsPreviewAPI';

View File

@ -1,3 +1,4 @@
/* eslint-disable import/no-extraneous-dependencies */
import Vue from 'vue';
import { createAddonDecorator, Render } from '../../index';
import { ContextsPreviewAPI } from '../ContextsPreviewAPI';

View File

@ -1,3 +1,4 @@
/* eslint-disable import/no-extraneous-dependencies */
import { createElement } from 'react';
import addons, { types } from '@storybook/addons';
import { ContextsManager } from './manager/ContextsManager';

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/addon-cssresources",
"version": "5.2.0-beta.37",
"version": "5.3.0-alpha.0",
"description": "A storybook addon to switch between css resources at runtime for your story",
"keywords": [
"addon",
@ -31,10 +31,10 @@
"prepare": "node ../../scripts/prepare.js"
},
"dependencies": {
"@storybook/addons": "5.2.0-beta.37",
"@storybook/api": "5.2.0-beta.37",
"@storybook/components": "5.2.0-beta.37",
"@storybook/core-events": "5.2.0-beta.37",
"@storybook/addons": "5.3.0-alpha.0",
"@storybook/api": "5.3.0-alpha.0",
"@storybook/components": "5.3.0-alpha.0",
"@storybook/core-events": "5.3.0-alpha.0",
"core-js": "^3.0.1",
"global": "^4.3.2",
"react": "^16.8.3"

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/addon-design-assets",
"version": "5.2.0-beta.37",
"version": "5.3.0-alpha.0",
"description": "Design asset preview for storybook",
"keywords": [
"addon",
@ -33,12 +33,12 @@
"prepare": "node ../../scripts/prepare.js"
},
"dependencies": {
"@storybook/addons": "5.2.0-beta.37",
"@storybook/api": "5.2.0-beta.37",
"@storybook/client-logger": "5.2.0-beta.37",
"@storybook/components": "5.2.0-beta.37",
"@storybook/core-events": "5.2.0-beta.37",
"@storybook/theming": "5.2.0-beta.37",
"@storybook/addons": "5.3.0-alpha.0",
"@storybook/api": "5.3.0-alpha.0",
"@storybook/client-logger": "5.3.0-alpha.0",
"@storybook/components": "5.3.0-alpha.0",
"@storybook/core-events": "5.3.0-alpha.0",
"@storybook/theming": "5.3.0-alpha.0",
"common-tags": "^1.8.0",
"core-js": "^3.0.1",
"global": "^4.3.2",

View File

@ -20,6 +20,7 @@ Read on to learn more:
- [Installation](#installation)
- [Preset options](#preset-options)
- [Manual configuration](#manual-configuration)
- [TypeScript configuration](#typescript-configuration)
- [More resources](#more-resources)
## DocsPage
@ -82,8 +83,8 @@ features as well. This chart captures the current state of support
| StoriesOf stories | + | + | + | + | + | + | + | + | + | + | + |
| Source | + | + | + | + | + | + | + | + | + | + | + |
| Notes / Info | + | + | + | + | + | + | + | + | + | + | + |
| Props table | + | + | # | | | | | | | | |
| Docgen | + | + | # | | | | | | | | |
| Props table | + | # | # | | | | | | | | |
| Docgen | + | # | # | | | | | | | | |
| Inline stories | + | # | | | | | | | | | |
**Note:** `#` = WIP support
@ -93,7 +94,7 @@ features as well. This chart captures the current state of support
First add the package. Make sure that the versions for your `@storybook/*` packages match:
```sh
yarn add -D @storybook/addon-docs
yarn add -D @storybook/addon-docs@next
```
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:
@ -161,7 +162,9 @@ module.exports = async ({ config }) => {
{
loader: 'babel-loader',
// may or may not need this line depending on your app's setup
plugins: ['@babel/plugin-transform-react-jsx'],
options: {
plugins: ['@babel/plugin-transform-react-jsx'],
},
},
{
loader: '@mdx-js/loader',
@ -188,11 +191,22 @@ import { addParameters } from '@storybook/react';
import { DocsPage, DocsContainer } from '@storybook/addon-docs/blocks';
addParameters({
docsContainer: DocsContainer,
docs: DocsPage,
docs: {
container: DocsContainer,
page: DocsPage,
},
});
```
## TypeScript configuration
SB Docs for React uses `babel-plugin-react-docgen` to extract Docgen comments from your code automatically. However, if you're using TypeScript, some extra configuration maybe required to get this information included in your docs.
1. You can add [react-docgen-typescript-loader](https://www.npmjs.com/package/react-docgen-typescript-loader) to your project by following the instructions there.
2. You can use [@storybook/preset-typescript](https://www.npmjs.com/package/@storybook/preset-typescript) which includes `react-docgen-typescript-loader`.
Install the preset with care. If you've already configured Typescript manually, that configuration may conflict with the preset. You can [debug your final webpack configuration with `--debug-webpack`](https://storybook.js.org/docs/configurations/custom-webpack-config/#debug-the-default-webpack-config).
## More resources
Want to learn more? Here are some more articles on Storybook Docs:

View File

@ -24,7 +24,7 @@ However, `DocsPage` brings the following improvements:
- It supports all frameworks that Storybook supports, including React, Vue, Angular and [many others](../README.md#framework-support).
- It generates better documentation that can be used as a standalone docs site, independently of Storybook.
- It supports better configuration, so you can capture project specific information with ease.
- It's built to work with [`MDX`](./mdx.md`) when you need more control of your documentation.
- It's built to work with [`MDX`](./mdx.md) when you need more control of your documentation.
## Component parameter
@ -196,7 +196,7 @@ And here are the return type signatures for each of the slot functions
What if you don't want a `DocsPage` for your storybook, for a specific component, or even for a specific story?
You can replace DocsPage at any level by overriding the `docs` parameter:
You can replace DocsPage at any level by overriding the `docs.page` parameter:
- With `null` to remove docs
- [With MDX](#csf-stories-with-mdx-docs) docs
@ -206,7 +206,7 @@ You can replace DocsPage at any level by overriding the `docs` parameter:
```js
import { addParameters } from '@storybook/react';
addParameters({ docs: null });
addParameters({ docs: { page: null } });
```
**Component-level (Button.stories.js)**
@ -216,7 +216,7 @@ import { Button } from './Button';
export default {
title: 'Demo/Button',
component: Button,
parameters: { docs: null },
parameters: { docs: { page: null } },
};
```
@ -227,7 +227,7 @@ import { Button } from './Button';
// export default { ... }
export const basic => () => <Button>Basic</Button>
basic.story = {
parameters: { docs: null }
parameters: { docs: { page: null } }
}
```

View File

@ -6,6 +6,7 @@
- [Pure MDX Stories](#pure-mdx-stories)
- [Mixed CSF / MDX Stories](#mixed-csf--mdx-stories)
- [CSF Stories with MDX Docs](#csf-stories-with-mdx-docs)
- [Mixing storiesOf with CSF/MDX](#mixing-storiesof-with-csfmdx)
- [Migrating from notes/info addons](#migrating-from-notesinfo-addons)
- [Exporting documentation](#exporting-documentation)
- [More resources](#more-resources)
@ -18,7 +19,7 @@ If you want to intersperse longform documentation in your Storybook, for example
## Pure MDX Stories
[MDX](mdx.md) is an alternative to syntax to CSF that allows you co-locate your stories and your documentation. Everything you can do in CSF, you can do in MDX. And if you're consuming it in [Webpack](https://webpack.js.org/), it exposes an _identical_ interface, so the two files are interchangeable. Some teams will choose to write all of their Storybook in MDX and never look back.
[MDX](mdx.md) is an alternative syntax to CSF that allows you to co-locate your stories and your documentation. Everything you can do in CSF, you can do in MDX. And if you're consuming it in [Webpack](https://webpack.js.org/), it exposes an _identical_ interface, so the two files are interchangeable. Some teams will choose to write all of their Storybook in MDX and never look back.
## Mixed CSF / MDX Stories
@ -56,7 +57,9 @@ import mdx from './Button.mdx';
export default {
title: 'Demo/Button',
parameters: {
docs: mdx,
docs: {
page: mdx,
},
},
};
@ -69,6 +72,34 @@ Note that in contrast to other examples, the MDX file suffix is `.mdx` rather th
2. You can refer to existing stories (i.e. `<Story id="...">`) but cannot define new stories (i.e. `<Story name="...">`).
3. The documentation gets exported as the default export (MDX default) rather than as a parameter hanging off the default export (CSF).
## Mixing storiesOf with CSF/MDX
You might have a collection of stories using the `storiesOf` API and want to add CSF/MDX piecemeal. Or you might have certain stories that are only possible with the `storiesOf` API (e.g. dynamically generated ones)
So how do you mix these two types? The first argument to `configure` can be a `require.context "req"`, an array of `req's`, or a `loader function`. The loader function should either return null or an array of module exports that include the default export. The default export is used by `configure` to load CSF/MDX files.
So here's a naive implementation of a loader function that assumes that none of your `storiesOf` files contains a default export, and filters out those exports:
```js
const loadFn = () => {
const req = require.context('../src', true, /\.stories\.js$/);
return req
.keys()
.map(fname => req(fname))
.filter(exp => !!exp.default);
};
configure(loadFn, module);
```
We could have baked this heuristic into Storybook, but we can't assume that your `storiesOf` files don't have default exports. If they do, you can filter them some other way (e.g. by file name).
If you don't filter out those files, you'll see the following error:
> "Loader function passed to 'configure' should return void or an array of module exports that all contain a 'default' export"
We made this error explicit to make sure you know what you're doing when you mix `storiesOf` and CSF/MDX.
## Migrating from notes/info addons
If you're currently using the notes/info addons, you can upgrade to DocsPage [using slots](./docspage.md#docspage-slots). There are different ways to use each addon, so you can adapt this recipe according to your use case.

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/addon-docs",
"version": "5.2.0-beta.37",
"version": "5.3.0-alpha.0",
"description": "Superior documentation for your components",
"keywords": [
"addon",
@ -42,12 +42,12 @@
"@mdx-js/loader": "^1.1.0",
"@mdx-js/mdx": "^1.1.0",
"@mdx-js/react": "^1.0.27",
"@storybook/addons": "5.2.0-beta.37",
"@storybook/api": "5.2.0-beta.37",
"@storybook/components": "5.2.0-beta.37",
"@storybook/router": "5.2.0-beta.37",
"@storybook/source-loader": "5.2.0-beta.37",
"@storybook/theming": "5.2.0-beta.37",
"@storybook/addons": "5.3.0-alpha.0",
"@storybook/api": "5.3.0-alpha.0",
"@storybook/components": "5.3.0-alpha.0",
"@storybook/router": "5.3.0-alpha.0",
"@storybook/source-loader": "5.3.0-alpha.0",
"@storybook/theming": "5.3.0-alpha.0",
"core-js": "^3.0.1",
"global": "^4.3.2",
"js-string-escape": "^1.0.1",

View File

@ -0,0 +1,11 @@
import React from 'react';
export const anchorBlockIdFromId = (storyId: string) => `anchor--${storyId}`;
export interface AnchorProps {
storyId: string;
}
export const Anchor: React.FC<AnchorProps> = ({ storyId, children }) => (
<div id={anchorBlockIdFromId(storyId)}>{children}</div>
);

View File

@ -1,11 +1,12 @@
/* eslint-disable react/destructuring-assignment */
import React from 'react';
import { document } from 'global';
import { MDXProvider } from '@mdx-js/react';
import { ThemeProvider, ensure as ensureTheme } from '@storybook/theming';
import { DocsWrapper, DocsContent, Source } from '@storybook/components';
import { components as htmlComponents, Code } from '@storybook/components/html';
import { DocsContextProps, DocsContext } from './DocsContext';
import { anchorBlockIdFromId } from './Anchor';
import { storyBlockIdFromId } from './Story';
interface DocsContainerProps {
context: DocsContextProps;
@ -44,11 +45,25 @@ export const DocsContainer: React.FunctionComponent<DocsContainerProps> = ({
context,
children,
}) => {
const parameters = (context && context.parameters) || {};
const { id: storyId = null, parameters = {} } = context || {};
const options = parameters.options || {};
const theme = ensureTheme(options.theme);
const { components: userComponents = null } = options.docs || {};
const { components: userComponents = null } = parameters.docs || {};
const components = { ...defaultComponents, ...userComponents };
React.useEffect(() => {
let element = document.getElementById(anchorBlockIdFromId(storyId));
if (!element) {
element = document.getElementById(storyBlockIdFromId(storyId));
}
if (element) {
element.scrollIntoView({
behavior: 'smooth',
block: 'end',
inline: 'nearest',
});
}
}, [storyId]);
return (
<DocsContext.Provider value={context}>
<ThemeProvider theme={theme}>

View File

@ -6,15 +6,11 @@ export interface DocsContextProps {
selectedStory?: string;
/**
* mdxKind is a statically-generated "kind" that corresponds to the
* component that's being documented in the MDX file, It's combined
* with the MDX story name `<Story name='story name'>...</Story>` to
* generate a storyId. In the case that the user is viewing a non-MDX
* story, the value of `mdxKind` will be the currently-selected kind.
* (I can't remember the corner case in which using the currentl-selected
* kind breaks down in MDX-defined stories, but there is one!)
* mdxStoryNameToId is an MDX-compiler-generated mapping of an MDX story's
* display name to its storyId. It's used internally by the `<Story>`
* doc block.
*/
mdxKind?: string;
mdxStoryNameToId?: Record<string, string>;
parameters?: any;
storyStore?: any;
forceRender?: () => void;

View File

@ -7,6 +7,7 @@ import { DocsContext } from './DocsContext';
import { Description, getDocgen } from './Description';
import { Story } from './Story';
import { Preview } from './Preview';
import { Anchor } from './Anchor';
import { getPropsTableProps } from './Props';
export interface SlotContext {
@ -34,9 +35,9 @@ export interface DocsPageProps {
interface DocsStoryProps {
id: string;
name: string;
description?: string;
expanded?: boolean;
withToolbar?: boolean;
parameters?: any;
}
interface StoryData {
@ -81,17 +82,19 @@ const StoryHeading = H3;
const DocsStory: React.FunctionComponent<DocsStoryProps> = ({
id,
name,
description,
expanded = true,
withToolbar = false,
parameters,
}) => (
<>
{expanded && <StoryHeading>{name}</StoryHeading>}
{expanded && description && <Description markdown={description} />}
<Anchor storyId={id}>
{expanded && <StoryHeading>{(parameters && parameters.displayName) || name}</StoryHeading>}
{expanded && parameters && parameters.docs && parameters.docs.storyDescription && (
<Description markdown={parameters.docs.storyDescription} />
)}
<Preview withToolbar={withToolbar}>
<Story id={id} />
</Preview>
</>
</Anchor>
);
export const DocsPage: React.FunctionComponent<DocsPageProps> = ({
@ -110,16 +113,14 @@ export const DocsPage: React.FunctionComponent<DocsPageProps> = ({
const propsTableProps = propsSlot(context);
const { selectedKind, storyStore } = context;
const componentStories = (storyStore.raw() as StoryData[]).filter(
s => s.kind === selectedKind
);
const componentStories = storyStore.getStoriesForKind(selectedKind);
const primary = primarySlot(componentStories, context);
const stories = storiesSlot(componentStories, context);
return (
<PureDocsPage title={title} subtitle={subtitle}>
<Description markdown={description} />
{primary && <DocsStory {...primary} expanded={false} withToolbar />}
{primary && <DocsStory key={primary.id} {...primary} expanded={false} withToolbar />}
{propsTableProps && <PropsTable {...propsTableProps} />}
{stories && stories.length > 0 && <StoriesHeading>Stories</StoriesHeading>}
{stories &&

View File

@ -1,6 +1,5 @@
import React, { ReactNodeArray } from 'react';
import { Preview as PurePreview, PreviewProps as PurePreviewProps } from '@storybook/components';
import { toId } from '@storybook/router';
import { getSourceProps } from './Source';
import { DocsContext, DocsContextProps } from './DocsContext';
@ -20,7 +19,7 @@ const getPreviewProps = (
children,
...props
}: PreviewProps & { children?: React.ReactNode },
{ mdxKind, storyStore }: DocsContextProps
{ mdxStoryNameToId, storyStore }: DocsContextProps
): PurePreviewProps => {
if (withSource === SourceState.NONE && !children) {
return props;
@ -29,7 +28,7 @@ const getPreviewProps = (
const stories = childArray.filter(
(c: React.ReactElement) => c.props && (c.props.id || c.props.name)
) as React.ReactElement[];
const targetIds = stories.map(s => s.props.id || toId(mdxKind, s.props.name));
const targetIds = stories.map(s => s.props.id || mdxStoryNameToId[s.props.name]);
const sourceProps = getSourceProps({ ids: targetIds }, { storyStore });
return {
...props, // pass through columns etc.

View File

@ -23,17 +23,16 @@ export const getPropsTableProps = (
{ exclude, of }: PropsProps,
{ parameters }: DocsContextProps
): PropsTableProps => {
const { component } = parameters;
try {
const params = parameters || {};
const { component, framework = null } = params;
const target = of === CURRENT_SELECTION ? component : of;
if (!target) {
throw new Error(PropsTableError.NO_COMPONENT);
}
const { framework = null } = parameters || {};
const { getPropDefs = inferPropDefs(framework) } =
(parameters && parameters.options && parameters.options.docs) || {};
const { getPropDefs = inferPropDefs(framework) } = params.docs || {};
if (!getPropDefs) {
throw new Error(PropsTableError.PROPS_UNSUPPORTED);
}

View File

@ -1,10 +1,18 @@
import React from 'react';
import { toId } from '@storybook/router';
import { MDXProvider } from '@mdx-js/react';
import { components as docsComponents } from '@storybook/components/html';
import { Story, StoryProps as PureStoryProps } from '@storybook/components';
import { CURRENT_SELECTION } from './shared';
import { DocsContext, DocsContextProps } from './DocsContext';
export const storyBlockIdFromId = (storyId: string) => `story--${storyId}`;
const resetComponents: Record<string, React.ElementType> = {};
Object.keys(docsComponents).forEach(key => {
resetComponents[key] = (props: any) => React.createElement(key, props);
});
interface CommonProps {
height?: string;
inline?: boolean;
@ -32,12 +40,12 @@ const inferInlineStories = (framework: string): boolean => {
export const getStoryProps = (
props: StoryProps,
{ id: currentId, storyStore, parameters, mdxKind }: DocsContextProps
{ id: currentId, storyStore, parameters, mdxStoryNameToId }: DocsContextProps
): PureStoryProps => {
const { id } = props as StoryRefProps;
const { name } = props as StoryDefProps;
const inputId = id === CURRENT_SELECTION ? currentId : id;
const previewId = inputId || toId(mdxKind, name);
const previewId = inputId || mdxStoryNameToId[name];
const { height, inline } = props;
const data = storyStore.fromId(previewId);
@ -45,7 +53,7 @@ export const getStoryProps = (
// prefer props, then global options, then framework-inferred values
const { inlineStories = inferInlineStories(framework), iframeHeight = undefined } =
(parameters && parameters.options && parameters.options.docs) || {};
(parameters && parameters.docs) || {};
return {
inline: typeof inline === 'boolean' ? inline : inlineStories,
id: previewId,
@ -59,7 +67,13 @@ const StoryContainer: React.FunctionComponent<StoryProps> = props => (
<DocsContext.Consumer>
{context => {
const storyProps = getStoryProps(props, context);
return <Story {...storyProps} />;
return (
<div id={storyBlockIdFromId(storyProps.id)}>
<MDXProvider components={resetComponents}>
<Story {...storyProps} />
</MDXProvider>
</div>
);
}}
</DocsContext.Consumer>
);

View File

@ -1,5 +1,6 @@
export { ColorPalette, ColorItem, IconGallery, IconItem, Typeset } from '@storybook/components';
export * from './Anchor';
export * from './Description';
export * from './DocsContext';
export * from './DocsPage';

View File

@ -3,6 +3,8 @@ import { addParameters } from '@storybook/angular';
import { DocsPage, DocsContainer } from '@storybook/addon-docs/blocks';
addParameters({
docsContainer: DocsContainer,
docs: DocsPage,
docs: {
container: DocsContainer,
page: DocsPage,
},
});

View File

@ -3,6 +3,8 @@ import { addParameters } from '@storybook/html';
import { DocsPage, DocsContainer } from '@storybook/addon-docs/blocks';
addParameters({
docsContainer: DocsContainer,
docs: DocsPage,
docs: {
container: DocsContainer,
page: DocsPage,
},
});

View File

@ -3,6 +3,8 @@ import { addParameters } from '@storybook/react';
import { DocsPage, DocsContainer } from '@storybook/addon-docs/blocks';
addParameters({
docsContainer: DocsContainer,
docs: DocsPage,
docs: {
container: DocsContainer,
page: DocsPage,
},
});

View File

@ -3,6 +3,8 @@ import { addParameters } from '@storybook/vue';
import { DocsPage, DocsContainer } from '@storybook/addon-docs/blocks';
addParameters({
docsContainer: DocsContainer,
docs: DocsPage,
docs: {
container: DocsContainer,
page: DocsPage,
},
});

View File

@ -53,6 +53,7 @@ MDXContent.isMDXComponent = true;
export const one = () => <Button>One</Button>;
one.story = {};
one.story.name = 'one';
one.story.parameters = { mdxSource: '<Button>One</Button>' };
one.story.decorators = [storyFn => <div className=\\"local\\">{storyFn()}</div>];
@ -72,12 +73,15 @@ const componentMeta = {
includeStories: ['one'],
};
const mdxKind = componentMeta.title;
const mdxStoryNameToId = { one: 'button--one' };
componentMeta.parameters = componentMeta.parameters || {};
componentMeta.parameters.docsContainer = ({ context, children }) => (
<DocsContainer context={{ ...context, mdxKind }}>{children}</DocsContainer>
);
componentMeta.parameters.docs = MDXContent;
componentMeta.parameters.docs = {
container: ({ context, children }) => (
<DocsContainer context={{ ...context, mdxStoryNameToId }}>{children}</DocsContainer>
),
page: MDXContent,
};
export default componentMeta;
"
@ -117,20 +121,23 @@ function MDXContent({ components, ...props }) {
MDXContent.isMDXComponent = true;
export const storybookDocsOnly = () => {
export const __page = () => {
throw new Error('Docs-only story');
};
storybookDocsOnly.story = { parameters: { docsOnly: true } };
__page.story = { parameters: { docsOnly: true } };
const componentMeta = { title: 'docs-only', includeStories: ['storybookDocsOnly'] };
const componentMeta = { title: 'docs-only', includeStories: ['__page'] };
const mdxStoryNameToId = {};
const mdxKind = componentMeta.title;
componentMeta.parameters = componentMeta.parameters || {};
componentMeta.parameters.docsContainer = ({ context, children }) => (
<DocsContainer context={{ ...context, mdxKind }}>{children}</DocsContainer>
);
componentMeta.parameters.docs = MDXContent;
componentMeta.parameters.docs = {
container: ({ context, children }) => (
<DocsContainer context={{ ...context, mdxStoryNameToId }}>{children}</DocsContainer>
),
page: MDXContent,
};
export default componentMeta;
"
@ -177,6 +184,7 @@ MDXContent.isMDXComponent = true;
export const one = () => <Button>One</Button>;
one.story = {};
one.story.name = 'one';
one.story.parameters = { mdxSource: '<Button>One</Button>' };
export const helloStory = () => <Button>Hello button</Button>;
@ -186,12 +194,15 @@ helloStory.story.parameters = { mdxSource: '<Button>Hello button</Button>' };
const componentMeta = { title: 'Button', includeStories: ['one', 'helloStory'] };
const mdxKind = componentMeta.title;
const mdxStoryNameToId = { one: 'button--one', 'hello story': 'button--hello-story' };
componentMeta.parameters = componentMeta.parameters || {};
componentMeta.parameters.docsContainer = ({ context, children }) => (
<DocsContainer context={{ ...context, mdxKind }}>{children}</DocsContainer>
);
componentMeta.parameters.docs = MDXContent;
componentMeta.parameters.docs = {
container: ({ context, children }) => (
<DocsContainer context={{ ...context, mdxStoryNameToId }}>{children}</DocsContainer>
),
page: MDXContent,
};
export default componentMeta;
"
@ -268,12 +279,18 @@ const componentMeta = {
includeStories: ['componentNotes', 'storyNotes'],
};
const mdxKind = componentMeta.title;
const mdxStoryNameToId = {
'component notes': 'button--component-notes',
'story notes': 'button--story-notes',
};
componentMeta.parameters = componentMeta.parameters || {};
componentMeta.parameters.docsContainer = ({ context, children }) => (
<DocsContainer context={{ ...context, mdxKind }}>{children}</DocsContainer>
);
componentMeta.parameters.docs = MDXContent;
componentMeta.parameters.docs = {
container: ({ context, children }) => (
<DocsContainer context={{ ...context, mdxStoryNameToId }}>{children}</DocsContainer>
),
page: MDXContent,
};
export default componentMeta;
"
@ -334,6 +351,7 @@ helloButton.story.parameters = { mdxSource: '<Button>Hello button</Button>' };
export const two = () => <Button>Two</Button>;
two.story = {};
two.story.name = 'two';
two.story.parameters = { mdxSource: '<Button>Two</Button>' };
const componentMeta = {
@ -344,12 +362,15 @@ const componentMeta = {
includeStories: ['helloButton', 'two'],
};
const mdxKind = componentMeta.title;
const mdxStoryNameToId = { 'hello button': 'button--hello-button', two: 'button--two' };
componentMeta.parameters = componentMeta.parameters || {};
componentMeta.parameters.docsContainer = ({ context, children }) => (
<DocsContainer context={{ ...context, mdxKind }}>{children}</DocsContainer>
);
componentMeta.parameters.docs = MDXContent;
componentMeta.parameters.docs = {
container: ({ context, children }) => (
<DocsContainer context={{ ...context, mdxStoryNameToId }}>{children}</DocsContainer>
),
page: MDXContent,
};
export default componentMeta;
"
@ -386,12 +407,15 @@ MDXContent.isMDXComponent = true;
const componentMeta = { includeStories: [] };
const mdxKind = componentMeta.title;
const mdxStoryNameToId = {};
componentMeta.parameters = componentMeta.parameters || {};
componentMeta.parameters.docsContainer = ({ context, children }) => (
<DocsContainer context={{ ...context, mdxKind }}>{children}</DocsContainer>
);
componentMeta.parameters.docs = MDXContent;
componentMeta.parameters.docs = {
container: ({ context, children }) => (
<DocsContainer context={{ ...context, mdxStoryNameToId }}>{children}</DocsContainer>
),
page: MDXContent,
};
export default componentMeta;
"
@ -431,16 +455,20 @@ MDXContent.isMDXComponent = true;
export const text = () => 'Plain text';
text.story = {};
text.story.name = 'text';
text.story.parameters = { mdxSource: \\"'Plain text'\\" };
const componentMeta = { title: 'Text', includeStories: ['text'] };
const mdxKind = componentMeta.title;
const mdxStoryNameToId = { text: 'text--text' };
componentMeta.parameters = componentMeta.parameters || {};
componentMeta.parameters.docsContainer = ({ context, children }) => (
<DocsContainer context={{ ...context, mdxKind }}>{children}</DocsContainer>
);
componentMeta.parameters.docs = MDXContent;
componentMeta.parameters.docs = {
container: ({ context, children }) => (
<DocsContainer context={{ ...context, mdxStoryNameToId }}>{children}</DocsContainer>
),
page: MDXContent,
};
export default componentMeta;
"
@ -487,6 +515,7 @@ MDXContent.isMDXComponent = true;
export const one = () => <Button>One</Button>;
one.story = {};
one.story.name = 'one';
one.story.parameters = { mdxSource: '<Button>One</Button>' };
export const helloStory = () => <Button>Hello button</Button>;
@ -501,12 +530,19 @@ wPunctuation.story.parameters = { mdxSource: '<Button>with punctuation</Button>'
const componentMeta = { title: 'Button', includeStories: ['one', 'helloStory', 'wPunctuation'] };
const mdxKind = componentMeta.title;
const mdxStoryNameToId = {
one: 'button--one',
'hello story': 'button--hello-story',
'w/punctuation': 'button--w-punctuation',
};
componentMeta.parameters = componentMeta.parameters || {};
componentMeta.parameters.docsContainer = ({ context, children }) => (
<DocsContainer context={{ ...context, mdxKind }}>{children}</DocsContainer>
);
componentMeta.parameters.docs = MDXContent;
componentMeta.parameters.docs = {
container: ({ context, children }) => (
<DocsContainer context={{ ...context, mdxStoryNameToId }}>{children}</DocsContainer>
),
page: MDXContent,
};
export default componentMeta;
"
@ -545,27 +581,30 @@ function MDXContent({ components, ...props }) {
MDXContent.isMDXComponent = true;
export const story0 = () => {
export const functionStory = () => {
const btn = document.createElement('button');
btn.innerHTML = 'Hello Button';
btn.addEventListener('click', action('Click'));
return btn;
};
story0.story = {};
story0.story.name = 'function';
story0.story.parameters = {
functionStory.story = {};
functionStory.story.name = 'function';
functionStory.story.parameters = {
mdxSource:
\\"() => {\\\\n const btn = document.createElement('button');\\\\n btn.innerHTML = 'Hello Button';\\\\n btn.addEventListener('click', action('Click'));\\\\n return btn;\\\\n}\\",
};
const componentMeta = { includeStories: ['story0'] };
const componentMeta = { includeStories: ['functionStory'] };
const mdxStoryNameToId = {};
const mdxKind = componentMeta.title;
componentMeta.parameters = componentMeta.parameters || {};
componentMeta.parameters.docsContainer = ({ context, children }) => (
<DocsContainer context={{ ...context, mdxKind }}>{children}</DocsContainer>
);
componentMeta.parameters.docs = MDXContent;
componentMeta.parameters.docs = {
container: ({ context, children }) => (
<DocsContainer context={{ ...context, mdxStoryNameToId }}>{children}</DocsContainer>
),
page: MDXContent,
};
export default componentMeta;
"
@ -631,12 +670,15 @@ toStorybook.story.parameters = {
const componentMeta = { title: 'MDX|Welcome', includeStories: ['toStorybook'] };
const mdxKind = componentMeta.title;
const mdxStoryNameToId = { 'to storybook': 'mdx-welcome--to-storybook' };
componentMeta.parameters = componentMeta.parameters || {};
componentMeta.parameters.docsContainer = ({ context, children }) => (
<DocsContainer context={{ ...context, mdxKind }}>{children}</DocsContainer>
);
componentMeta.parameters.docs = MDXContent;
componentMeta.parameters.docs = {
container: ({ context, children }) => (
<DocsContainer context={{ ...context, mdxStoryNameToId }}>{children}</DocsContainer>
),
page: MDXContent,
};
export default componentMeta;
"
@ -673,12 +715,15 @@ MDXContent.isMDXComponent = true;
const componentMeta = { includeStories: [] };
const mdxKind = componentMeta.title;
const mdxStoryNameToId = {};
componentMeta.parameters = componentMeta.parameters || {};
componentMeta.parameters.docsContainer = ({ context, children }) => (
<DocsContainer context={{ ...context, mdxKind }}>{children}</DocsContainer>
);
componentMeta.parameters.docs = MDXContent;
componentMeta.parameters.docs = {
container: ({ context, children }) => (
<DocsContainer context={{ ...context, mdxStoryNameToId }}>{children}</DocsContainer>
),
page: MDXContent,
};
export default componentMeta;
"
@ -716,12 +761,15 @@ MDXContent.isMDXComponent = true;
const componentMeta = { includeStories: [] };
const mdxKind = componentMeta.title;
const mdxStoryNameToId = {};
componentMeta.parameters = componentMeta.parameters || {};
componentMeta.parameters.docsContainer = ({ context, children }) => (
<DocsContainer context={{ ...context, mdxKind }}>{children}</DocsContainer>
);
componentMeta.parameters.docs = MDXContent;
componentMeta.parameters.docs = {
container: ({ context, children }) => (
<DocsContainer context={{ ...context, mdxStoryNameToId }}>{children}</DocsContainer>
),
page: MDXContent,
};
export default componentMeta;
"

View File

@ -3,6 +3,7 @@ const parser = require('@babel/parser');
const generate = require('@babel/generator').default;
const camelCase = require('lodash/camelCase');
const jsStringEscape = require('js-string-escape');
const { toId, storyNameFromExport } = require('@storybook/router/utils');
// Generate the MDX as is, but append named exports for every
// story in the contents
@ -17,17 +18,19 @@ function getAttr(elt, what) {
return attr && attr.value;
}
function getStoryFn(name, counter) {
if (name) {
const storyFn = camelCase(name.replace(/[^a-z0-9-]/g, '-'));
if (storyFn.length > 1 && !RESERVED.exec(storyFn)) {
return storyFn;
}
}
return `story${counter}`;
}
const isReserved = name => RESERVED.exec(name);
function genStoryExport(ast, counter) {
const sanitizeName = name => {
let key = camelCase(name);
if (isReserved(key)) {
key = `${key}Story`;
}
return key;
};
const getStoryKey = (name, counter) => (name ? sanitizeName(name) : `story${counter}`);
function genStoryExport(ast, context) {
let storyName = getAttr(ast.openingElement, 'name');
let storyId = getAttr(ast.openingElement, 'id');
storyName = storyName && storyName.value;
@ -45,7 +48,7 @@ function genStoryExport(ast, counter) {
// console.log('genStoryExport', JSON.stringify(ast, null, 2));
const statements = [];
const storyKey = getStoryFn(storyName, counter);
const storyKey = getStoryKey(storyName, context.counter);
let body = ast.children.find(n => n.type !== 'JSXText');
let storyCode = null;
@ -72,9 +75,8 @@ function genStoryExport(ast, counter) {
}
statements.push(`${storyKey}.story = {};`);
if (storyName !== storyKey) {
statements.push(`${storyKey}.story.name = '${storyName}';`);
}
// always preserve the name, since CSF exports can get modified by displayName
statements.push(`${storyKey}.story.name = '${storyName}';`);
let parameters = getAttr(ast.openingElement, 'parameters');
parameters = parameters && parameters.expression;
@ -94,23 +96,26 @@ function genStoryExport(ast, counter) {
statements.push(`${storyKey}.story.decorators = ${decos};`);
}
// eslint-disable-next-line no-param-reassign
context.storyNameToKey[storyName] = storyKey;
return {
[storyKey]: statements.join('\n'),
};
}
function genPreviewExports(ast, counter) {
function genPreviewExports(ast, context) {
// console.log('genPreviewExports', JSON.stringify(ast, null, 2));
let localCounter = counter;
const previewExports = {};
for (let i = 0; i < ast.children.length; i += 1) {
const child = ast.children[i];
if (child.type === 'JSXElement' && child.openingElement.name.name === 'Story') {
const storyExport = genStoryExport(child, localCounter);
const storyExport = genStoryExport(child, context);
if (storyExport) {
Object.assign(previewExports, storyExport);
localCounter += 1;
// eslint-disable-next-line no-param-reassign
context.counter += 1;
}
}
}
@ -163,12 +168,16 @@ function getExports(node, counter) {
// insert `mdxKind` into the context so that we can know what "kind" we're rendering into
// when we render <Story name="xxx">...</Story>, since this MDX can be attached to any `selectedKind`!
const wrapperJs = `
const mdxKind = componentMeta.title;
componentMeta.parameters = componentMeta.parameters || {};
componentMeta.parameters.docsContainer = ({ context, children }) => <DocsContainer context={{...context, mdxKind}}>{children}</DocsContainer>;
componentMeta.parameters.docs = MDXContent;
componentMeta.parameters.docs = {
container: ({ context, children }) => <DocsContainer context={{...context, mdxStoryNameToId}}>{children}</DocsContainer>,
page: MDXContent,
};
`.trim();
// Use this rather than JSON.stringify because `Meta`'s attributes
// are already valid code strings, so we want to insert them raw
// rather than add an extra set of quotes
function stringifyMeta(meta) {
let result = '{ ';
Object.entries(meta).forEach(([key, val]) => {
@ -186,16 +195,18 @@ function extractExports(node, options) {
const storyExports = [];
const includeStories = [];
let metaExport = null;
let counter = 0;
const context = {
counter: 0,
storyNameToKey: {},
};
node.children.forEach(n => {
const exports = getExports(n, counter);
const exports = getExports(n, context);
if (exports) {
const { stories, meta } = exports;
if (stories) {
Object.entries(stories).forEach(([key, story]) => {
includeStories.push(key);
storyExports.push(story);
counter += 1;
});
}
if (meta) {
@ -208,22 +219,32 @@ function extractExports(node, options) {
});
if (metaExport) {
if (!storyExports.length) {
storyExports.push(
'export const storybookDocsOnly = () => { throw new Error("Docs-only story"); };'
);
storyExports.push('storybookDocsOnly.story = { parameters: { docsOnly: true } };');
includeStories.push('storybookDocsOnly');
storyExports.push('export const __page = () => { throw new Error("Docs-only story"); };');
storyExports.push('__page.story = { parameters: { docsOnly: true } };');
includeStories.push('__page');
}
} else {
metaExport = {};
}
metaExport.includeStories = JSON.stringify(includeStories);
const { title } = metaExport;
const mdxStoryNameToId = Object.entries(context.storyNameToKey).reduce(
(acc, [storyName, storyKey]) => {
if (title) {
acc[storyName] = toId(title, storyNameFromExport(storyKey));
}
return acc;
},
{}
);
const fullJsx = [
'import { DocsContainer } from "@storybook/addon-docs/blocks";',
defaultJsx,
...storyExports,
`const componentMeta = ${stringifyMeta(metaExport)};`,
`const mdxStoryNameToId = ${JSON.stringify(mdxStoryNameToId)};`,
wrapperJs,
'export default componentMeta;',
].join('\n\n');

View File

@ -1,2 +1,3 @@
declare module '@mdx-js/react';
declare module '@storybook/addon-docs/mdx-compiler-plugin';
declare module 'global';

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/addon-events",
"version": "5.2.0-beta.37",
"version": "5.3.0-alpha.0",
"description": "Add events to your Storybook stories.",
"keywords": [
"addon",
@ -30,11 +30,11 @@
"prepare": "node ../../scripts/prepare.js"
},
"dependencies": {
"@storybook/addons": "5.2.0-beta.37",
"@storybook/api": "5.2.0-beta.37",
"@storybook/client-api": "5.2.0-beta.37",
"@storybook/core-events": "5.2.0-beta.37",
"@storybook/theming": "5.2.0-beta.37",
"@storybook/addons": "5.3.0-alpha.0",
"@storybook/api": "5.3.0-alpha.0",
"@storybook/client-api": "5.3.0-alpha.0",
"@storybook/core-events": "5.3.0-alpha.0",
"@storybook/theming": "5.3.0-alpha.0",
"core-js": "^3.0.1",
"format-json": "^1.0.3",
"lodash": "^4.17.11",

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/addon-google-analytics",
"version": "5.2.0-beta.37",
"version": "5.3.0-alpha.0",
"description": "Storybook addon for google analytics",
"keywords": [
"addon",
@ -20,8 +20,8 @@
"prepare": "node ../../scripts/prepare.js"
},
"dependencies": {
"@storybook/addons": "5.2.0-beta.37",
"@storybook/core-events": "5.2.0-beta.37",
"@storybook/addons": "5.3.0-alpha.0",
"@storybook/core-events": "5.3.0-alpha.0",
"core-js": "^3.0.1",
"global": "^4.3.2",
"react-ga": "^2.5.7"

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/addon-graphql",
"version": "5.2.0-beta.37",
"version": "5.3.0-alpha.0",
"description": "Storybook addon to display the GraphiQL IDE",
"keywords": [
"addon",
@ -28,8 +28,8 @@
"prepare": "node ../../scripts/prepare.js"
},
"dependencies": {
"@storybook/addons": "5.2.0-beta.37",
"@storybook/api": "5.2.0-beta.37",
"@storybook/addons": "5.3.0-alpha.0",
"@storybook/api": "5.3.0-alpha.0",
"core-js": "^3.0.1",
"global": "^4.3.2",
"graphiql": "^0.13.0",

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/addon-info",
"version": "5.2.0-beta.37",
"version": "5.3.0-alpha.0",
"description": "A Storybook addon to show additional information for your stories.",
"keywords": [
"addon",
@ -27,10 +27,10 @@
"prepare": "node ../../scripts/prepare.js"
},
"dependencies": {
"@storybook/addons": "5.2.0-beta.37",
"@storybook/client-logger": "5.2.0-beta.37",
"@storybook/components": "5.2.0-beta.37",
"@storybook/theming": "5.2.0-beta.37",
"@storybook/addons": "5.3.0-alpha.0",
"@storybook/client-logger": "5.3.0-alpha.0",
"@storybook/components": "5.3.0-alpha.0",
"@storybook/theming": "5.3.0-alpha.0",
"core-js": "^3.0.1",
"global": "^4.3.2",
"jsx-to-string": "^1.4.0",

View File

@ -26,6 +26,7 @@ exports[`addon Info should render <Info /> and external markdown 1`] = `
maxPropObjectKeys={3}
maxPropStringLength={50}
maxPropsIntoLine={3}
propTableCompare={[Function]}
propTables={Array []}
propTablesExclude={Array []}
showHeader={true}
@ -160,6 +161,7 @@ containing **bold**, *cursive* text, \`code\` and [a link](https://github.com)"
maxPropObjectKeys={3}
maxPropStringLength={50}
maxPropsIntoLine={3}
propTableCompare={[Function]}
propTables={Array []}
propTablesExclude={Array []}
showHeader={true}
@ -292,6 +294,7 @@ exports[`addon Info should render <Info /> for memoized component 1`] = `
maxPropObjectKeys={3}
maxPropStringLength={50}
maxPropsIntoLine={3}
propTableCompare={[Function]}
propTables={null}
propTablesExclude={Array []}
showHeader={true}
@ -821,6 +824,7 @@ exports[`addon Info should render component description if story kind matches co
maxPropObjectKeys={3}
maxPropStringLength={50}
maxPropsIntoLine={3}
propTableCompare={[Function]}
propTables={null}
propTablesExclude={Array []}
showHeader={true}
@ -5379,6 +5383,7 @@ exports[`addon Info should render component description if story name matches co
maxPropObjectKeys={3}
maxPropStringLength={50}
maxPropsIntoLine={3}
propTableCompare={[Function]}
propTables={null}
propTablesExclude={Array []}
showHeader={true}

View File

@ -302,6 +302,7 @@ class Story extends Component {
const {
children,
propTablesExclude,
propTableCompare,
maxPropObjectKeys,
maxPropArrayLength,
maxPropStringLength,
@ -349,7 +350,7 @@ class Story extends Component {
(propTables.length > 0 && // if propTables is set and has items in it
!propTables.includes(innerChildren.type)) || // ignore types that are missing from propTables
(Array.isArray(propTablesExclude) && // also ignore excluded types
~propTablesExclude.indexOf(innerChildren.type)) // eslint-disable-line no-bitwise
propTablesExclude.some(Comp => propTableCompare(innerChildren, Comp)))
) {
return;
}
@ -409,6 +410,7 @@ Story.propTypes = {
info: PropTypes.oneOfType([PropTypes.string, PropTypes.node]),
propTables: PropTypes.arrayOf(PropTypes.func),
propTablesExclude: PropTypes.arrayOf(PropTypes.func),
propTableCompare: PropTypes.func.isRequired,
showInline: PropTypes.bool,
showHeader: PropTypes.bool,
showSource: PropTypes.bool,

View File

@ -13,6 +13,12 @@ const defaultOptions = {
header: true,
source: true,
propTables: [],
propTableCompare: (element, Component) =>
// https://github.com/gaearon/react-hot-loader#checking-element-types
typeof reactHotLoaderGlobal === 'undefined'
? element.type === Component
: // eslint-disable-next-line no-undef
reactHotLoaderGlobal.areComponentsEqual(element.type, Component),
TableComponent: PropTable,
maxPropsIntoLine: 3,
maxPropObjectKeys: 3,
@ -73,6 +79,7 @@ function addInfo(storyFn, context, infoOptions) {
: s => nestedObjectAssign({}, s, options.styles),
propTables: options.propTables,
propTablesExclude: options.propTablesExclude,
propTableCompare: options.propTableCompare,
PropTable: makeTableComponent(options.TableComponent),
components,
maxPropObjectKeys: options.maxPropObjectKeys,

View File

@ -26,14 +26,14 @@ When running **Jest**, be sure to save the results in a json file:
```js
"scripts": {
"test:generate-output": "jest --json --outputFile=jest-test-results.json"
"test:generate-output": "jest --json --outputFile=.jest-test-results.json"
}
```
You may want to add it the result file to `.gitignore`, since it's a generated file:
```
jest-test-results.json
.jest-test-results.json
```
But much like lockfiles and snapshots checking-in generated files can have certain advantages as well. It's up to you.

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/addon-jest",
"version": "5.2.0-beta.37",
"version": "5.3.0-alpha.0",
"description": "React storybook addon that show component jest report",
"keywords": [
"addon",
@ -34,11 +34,11 @@
"prepare": "node ../../scripts/prepare.js"
},
"dependencies": {
"@storybook/addons": "5.2.0-beta.37",
"@storybook/api": "5.2.0-beta.37",
"@storybook/components": "5.2.0-beta.37",
"@storybook/core-events": "5.2.0-beta.37",
"@storybook/theming": "5.2.0-beta.37",
"@storybook/addons": "5.3.0-alpha.0",
"@storybook/api": "5.3.0-alpha.0",
"@storybook/components": "5.3.0-alpha.0",
"@storybook/core-events": "5.3.0-alpha.0",
"@storybook/theming": "5.3.0-alpha.0",
"core-js": "^3.0.1",
"global": "^4.3.2",
"react": "^16.8.3",

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/addon-knobs",
"version": "5.2.0-beta.37",
"version": "5.3.0-alpha.0",
"description": "Storybook Addon Prop Editor Component",
"keywords": [
"addon",
@ -35,12 +35,13 @@
"prepare": "node ../../scripts/prepare.js"
},
"dependencies": {
"@storybook/addons": "5.2.0-beta.37",
"@storybook/api": "5.2.0-beta.37",
"@storybook/client-api": "5.2.0-beta.37",
"@storybook/components": "5.2.0-beta.37",
"@storybook/core-events": "5.2.0-beta.37",
"@storybook/theming": "5.2.0-beta.37",
"@storybook/addons": "5.3.0-alpha.0",
"@storybook/api": "5.3.0-alpha.0",
"@storybook/client-api": "5.3.0-alpha.0",
"@storybook/components": "5.3.0-alpha.0",
"@storybook/core-events": "5.3.0-alpha.0",
"@storybook/theming": "5.3.0-alpha.0",
"@types/react-color": "^3.0.1",
"copy-to-clipboard": "^3.0.8",
"core-js": "^3.0.1",
"escape-html": "^1.0.3",
@ -55,7 +56,6 @@
},
"devDependencies": {
"@types/escape-html": "0.0.20",
"@types/react-color": "^3.0.1",
"@types/react-lifecycles-compat": "^3.0.1",
"@types/react-select": "^2.0.19"
},

View File

@ -106,7 +106,7 @@ expectKnobOfType<string>(
},
'none'
),
select('select with string array', ['yes', 'no'], 'yes'),
select<string>('select with string array', ['yes', 'no'], 'yes'),
select('select with string literal array', stringLiteralArray, stringLiteralArray[0]),
select('select with readonly array', ['red', 'blue'] as const, 'red'),
select<ButtonVariant>('select with string enum options', ButtonVariant, ButtonVariant.primary)
@ -123,7 +123,7 @@ expectKnobOfType<number>(
{ 'type a': SomeEnum.Type1, 'type b': SomeEnum.Type2 },
SomeEnum.Type2
),
select('select with number array', [1, 2, 3, 4], 1),
select<number>('select with number array', [1, 2, 3, 4], 1),
select('select with readonly number array', [1, 2] as const, 1)
);
@ -131,6 +131,60 @@ expectKnobOfType<number | null>(
select('select with null option', { a: 1, b: null }, null, groupId)
);
expectKnobOfType<string | string[]>(
select(
'select with string and string array options',
{
Red: 'red',
Blue: 'blue',
Yellow: 'yellow',
Rainbow: ['red', 'orange', 'etc'],
None: 'transparent',
},
'red'
)
);
expectKnobOfType<number | number[]>(
select(
'select with number and number array options',
{
Red: 1,
Blue: 2,
Yellow: 3,
Rainbow: [4, 5, 6],
None: 7,
},
7
)
);
expectKnobOfType<string | string[] | null>(
select(
'select with string, string array, and null options',
{
Red: 'red',
Blue: 'blue',
Yellow: 'yellow',
Rainbow: ['red', 'orange', 'etc'],
None: null,
},
null
)
);
expectKnobOfType<number[]>(
select(
'select with number array options',
{
ones: [1],
twos: [2, 2],
threes: [3, 3, 3],
},
[1]
)
);
/** Object knob */
expectKnobOfType(
@ -163,6 +217,68 @@ expectKnobOfType(
options('options with group', {}, '', { display: 'check' })
);
expectKnobOfType<number | null>(
options('select with null option', { a: 1, b: null }, null, { display: 'check' })
);
expectKnobOfType<string | string[]>(
options(
'options with string and string array options',
{
Red: 'red',
Blue: 'blue',
Yellow: 'yellow',
Rainbow: ['red', 'orange', 'etc'],
None: 'transparent',
},
'red',
{ display: 'check' }
)
);
expectKnobOfType<number | number[]>(
options(
'select with number and number array options',
{
Red: 1,
Blue: 2,
Yellow: 3,
Rainbow: [4, 5, 6],
None: 7,
},
7,
{ display: 'check' }
)
);
expectKnobOfType<string | string[] | null>(
options(
'select with string, string array, and null options',
{
Red: 'red',
Blue: 'blue',
Yellow: 'yellow',
Rainbow: ['red', 'orange', 'etc'],
None: null,
},
null,
{ display: 'check' }
)
);
expectKnobOfType<number[]>(
options(
'select with number array options',
{
ones: [1],
twos: [2, 2],
threes: [3, 3, 3],
},
[1],
{ display: 'check' }
)
);
/** Array knob */
const arrayReadonly = array('array as readonly', ['hi', 'there'] as const);

View File

@ -9,7 +9,14 @@ import CheckboxesType from './Checkboxes';
// TODO: Apply the Storybook theme to react-select
export type OptionsTypeKnobSingleValue = string | number | null | undefined;
export type OptionsTypeKnobSingleValue =
| string
| number
| null
| undefined
| string[]
| number[]
| (string | number)[];
export type OptionsTypeKnobValue<
T extends OptionsTypeKnobSingleValue = OptionsTypeKnobSingleValue
@ -24,7 +31,7 @@ export type OptionsKnobOptionsDisplay =
| 'multi-select';
export interface OptionsKnobOptions {
display?: OptionsKnobOptionsDisplay;
display: OptionsKnobOptionsDisplay;
}
export interface OptionsTypeKnob<T extends OptionsTypeKnobValue> extends KnobControlConfig<T> {

View File

@ -4,13 +4,13 @@ import PropTypes from 'prop-types';
import { Form } from '@storybook/components';
import { KnobControlConfig, KnobControlProps } from './types';
export type SelectTypeKnobValue = string | number | null | undefined;
export type SelectTypeKnobValue = string | number | null | undefined | PropertyKey[];
export type SelectTypeOptionsProp<T extends SelectTypeKnobValue = SelectTypeKnobValue> =
| Record<string | number, T>
| Record<Exclude<T, null | undefined>, T[keyof T]>
| Exclude<T, null | undefined>[]
| readonly Exclude<T, null | undefined>[];
| Record<PropertyKey, T>
| Record<Extract<T, PropertyKey>, T[keyof T]>
| Extract<T, PropertyKey>[]
| readonly Extract<T, PropertyKey>[];
export interface SelectTypeKnob<T extends SelectTypeKnobValue = SelectTypeKnobValue>
extends KnobControlConfig<T> {
@ -31,8 +31,8 @@ const SelectType: FunctionComponent<SelectTypeProps> & {
} = ({ knob, onChange }) => {
const { options } = knob;
const entries = Array.isArray(options)
? options.reduce<Record<string, SelectTypeKnobValue>>((acc, k) => ({ ...acc, [k]: k }), {})
: (options as Record<string, SelectTypeKnobValue>);
? options.reduce<Record<PropertyKey, SelectTypeKnobValue>>((acc, k) => ({ ...acc, [k]: k }), {})
: (options as Record<PropertyKey, SelectTypeKnobValue>);
const selectedKey = Object.keys(entries).find(k => {
if (Array.isArray(knob.value)) {

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/addon-links",
"version": "5.2.0-beta.37",
"version": "5.3.0-alpha.0",
"description": "Story Links addon for storybook",
"keywords": [
"addon",
@ -29,9 +29,9 @@
"prepare": "node ../../scripts/prepare.js"
},
"dependencies": {
"@storybook/addons": "5.2.0-beta.37",
"@storybook/core-events": "5.2.0-beta.37",
"@storybook/router": "5.2.0-beta.37",
"@storybook/addons": "5.3.0-alpha.0",
"@storybook/core-events": "5.3.0-alpha.0",
"@storybook/router": "5.3.0-alpha.0",
"common-tags": "^1.8.0",
"core-js": "^3.0.1",
"global": "^4.3.2",

View File

@ -4,7 +4,9 @@ import EVENTS, { ADDON_ID } from './constants';
export const register = () => {
addons.register(ADDON_ID, api => {
api.on(EVENTS.REQUEST, ({ kind, name }) => {
const channel = addons.getChannel();
channel.on(EVENTS.REQUEST, ({ kind, name }) => {
const id = api.storyId(kind, name);
api.emit(EVENTS.RECEIVE, id);
});

View File

@ -1,15 +1,19 @@
import { document, HTMLElement } from 'global';
import qs from 'qs';
import addons from '@storybook/addons';
import { SELECT_STORY, STORY_CHANGED } from '@storybook/core-events';
import { STORY_CHANGED, SELECT_STORY } from '@storybook/core-events';
import { toId } from '@storybook/router/utils';
interface Params {
interface ParamsId {
storyId: string;
}
interface ParamsCombo {
kind: string;
story: string;
}
export const navigate = (params: Params) => addons.getChannel().emit(SELECT_STORY, params);
export const navigate = (params: ParamsId | ParamsCombo) =>
addons.getChannel().emit(SELECT_STORY, params);
const generateUrl = (id: string) => {
const { location } = document;
@ -25,6 +29,7 @@ const valueOrCall = (args: string[]) => (value: string | ((...args: string[]) =>
export const linkTo = (kind: string, story?: string) => (...args: string[]) => {
const resolver = valueOrCall(args);
navigate({
kind: resolver(kind),
story: resolver(story),

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/addon-notes",
"version": "5.2.0-beta.37",
"version": "5.3.0-alpha.0",
"description": "Write notes for your Storybook stories.",
"keywords": [
"addon",
@ -30,13 +30,13 @@
"prepare": "node ../../scripts/prepare.js"
},
"dependencies": {
"@storybook/addons": "5.2.0-beta.37",
"@storybook/api": "5.2.0-beta.37",
"@storybook/client-logger": "5.2.0-beta.37",
"@storybook/components": "5.2.0-beta.37",
"@storybook/core-events": "5.2.0-beta.37",
"@storybook/router": "5.2.0-beta.37",
"@storybook/theming": "5.2.0-beta.37",
"@storybook/addons": "5.3.0-alpha.0",
"@storybook/api": "5.3.0-alpha.0",
"@storybook/client-logger": "5.3.0-alpha.0",
"@storybook/components": "5.3.0-alpha.0",
"@storybook/core-events": "5.3.0-alpha.0",
"@storybook/router": "5.3.0-alpha.0",
"@storybook/theming": "5.3.0-alpha.0",
"core-js": "^3.0.1",
"global": "^4.3.2",
"markdown-to-jsx": "^6.10.3",

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/addon-ondevice-actions",
"version": "5.2.0-beta.37",
"version": "5.3.0-alpha.0",
"description": "Action Logger addon for react-native storybook",
"keywords": [
"storybook"
@ -25,13 +25,13 @@
"prepare": "node ../../scripts/prepare.js"
},
"dependencies": {
"@storybook/addons": "5.2.0-beta.37",
"@storybook/core-events": "5.2.0-beta.37",
"@storybook/addons": "5.3.0-alpha.0",
"@storybook/core-events": "5.3.0-alpha.0",
"core-js": "^3.0.1",
"fast-deep-equal": "^2.0.1"
},
"devDependencies": {
"@storybook/addon-actions": "5.2.0-beta.37"
"@storybook/addon-actions": "5.3.0-alpha.0"
},
"peerDependencies": {
"@storybook/addon-actions": "*",

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/addon-ondevice-backgrounds",
"version": "5.2.0-beta.37",
"version": "5.3.0-alpha.0",
"description": "A react-native storybook addon to show different backgrounds for your preview",
"keywords": [
"addon",
@ -29,7 +29,7 @@
"prepare": "node ../../scripts/prepare.js"
},
"dependencies": {
"@storybook/addons": "5.2.0-beta.37",
"@storybook/addons": "5.3.0-alpha.0",
"core-js": "^3.0.1",
"prop-types": "^15.7.2"
},

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/addon-ondevice-knobs",
"version": "5.2.0-beta.37",
"version": "5.3.0-alpha.0",
"description": "Display storybook story knobs on your deviced.",
"keywords": [
"addon",
@ -26,8 +26,8 @@
"prepare": "node ../../scripts/prepare.js"
},
"dependencies": {
"@storybook/addons": "5.2.0-beta.37",
"@storybook/core-events": "5.2.0-beta.37",
"@storybook/addons": "5.3.0-alpha.0",
"@storybook/core-events": "5.3.0-alpha.0",
"core-js": "^3.0.1",
"deep-equal": "^1.0.1",
"prop-types": "^15.7.2",

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/addon-ondevice-notes",
"version": "5.2.0-beta.37",
"version": "5.3.0-alpha.0",
"description": "Write notes for your react-native Storybook stories.",
"keywords": [
"addon",
@ -25,8 +25,8 @@
"prepare": "node ../../scripts/prepare.js"
},
"dependencies": {
"@storybook/addons": "5.2.0-beta.37",
"@storybook/client-logger": "5.2.0-beta.37",
"@storybook/addons": "5.3.0-alpha.0",
"@storybook/client-logger": "5.3.0-alpha.0",
"core-js": "^3.0.1",
"prop-types": "^15.7.2",
"react-native-simple-markdown": "^1.1.0"

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/addon-options",
"version": "5.2.0-beta.37",
"version": "5.3.0-alpha.0",
"description": "Options addon for storybook",
"keywords": [
"addon",
@ -28,7 +28,7 @@
"prepare": "node ../../scripts/prepare.js"
},
"dependencies": {
"@storybook/addons": "5.2.0-beta.37",
"@storybook/addons": "5.3.0-alpha.0",
"core-js": "^3.0.1",
"util-deprecate": "^1.0.2"
},

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/addon-queryparams",
"version": "5.2.0-beta.37",
"version": "5.3.0-alpha.0",
"description": "parameter addon for storybook",
"keywords": [
"addon",
@ -28,12 +28,12 @@
"prepare": "node ../../scripts/prepare.js"
},
"dependencies": {
"@storybook/addons": "5.2.0-beta.37",
"@storybook/api": "5.2.0-beta.37",
"@storybook/client-logger": "5.2.0-beta.37",
"@storybook/components": "5.2.0-beta.37",
"@storybook/core-events": "5.2.0-beta.37",
"@storybook/theming": "5.2.0-beta.37",
"@storybook/addons": "5.3.0-alpha.0",
"@storybook/api": "5.3.0-alpha.0",
"@storybook/client-logger": "5.3.0-alpha.0",
"@storybook/components": "5.3.0-alpha.0",
"@storybook/core-events": "5.3.0-alpha.0",
"@storybook/theming": "5.3.0-alpha.0",
"common-tags": "^1.8.0",
"core-js": "^3.0.1",
"global": "^4.3.2",

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/addon-storyshots",
"version": "5.2.0-beta.37",
"version": "5.3.0-alpha.0",
"description": "StoryShots is a Jest Snapshot Testing Addon for Storybook.",
"keywords": [
"addon",
@ -29,7 +29,7 @@
"storybook": "start-storybook -p 6006"
},
"dependencies": {
"@storybook/addons": "5.2.0-beta.37",
"@storybook/addons": "5.3.0-alpha.0",
"core-js": "^3.0.1",
"glob": "^7.1.3",
"global": "^4.3.2",

View File

@ -166,6 +166,7 @@ exports[`Storyshots Welcome to Storybook 1`] = `
onClick={[Function]}
>
<button
onClick={[Function]}
style={
Object {
"backgroundColor": "transparent",
@ -272,6 +273,7 @@ exports[`Storyshots Welcome to Storybook 1`] = `
"textDecoration": "none",
}
}
target="_blank"
>
Writing Stories
</a>

View File

@ -139,6 +139,7 @@ exports[`Storyshots Welcome to Storybook 1`] = `
<p>
See these sample
<button
onClick={[Function]}
style={
Object {
"backgroundColor": "transparent",
@ -233,6 +234,7 @@ exports[`Storyshots Welcome to Storybook 1`] = `
"textDecoration": "none",
}
}
target="_blank"
>
Writing Stories
</a>

View File

@ -43,6 +43,7 @@ exports[`Storyshots Welcome to Storybook 1`] = `
<p>
See these sample
<button
onClick={[Function]}
style={
Object {
"backgroundColor": "transparent",
@ -137,6 +138,7 @@ exports[`Storyshots Welcome to Storybook 1`] = `
"textDecoration": "none",
}
}
target="_blank"
>
Writing Stories
</a>

View File

@ -43,6 +43,7 @@ exports[`Storyshots Welcome to Storybook 1`] = `
<p>
See these sample
<button
onClick={[Function]}
style={
Object {
"backgroundColor": "transparent",
@ -137,6 +138,7 @@ exports[`Storyshots Welcome to Storybook 1`] = `
"textDecoration": "none",
}
}
target="_blank"
>
Writing Stories
</a>

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/addon-storyshots-puppeteer",
"version": "5.2.0-beta.37",
"version": "5.3.0-alpha.0",
"description": "Image snapshots addition to StoryShots based on puppeteer",
"keywords": [
"addon",
@ -26,8 +26,8 @@
"prepare": "node ../../../scripts/prepare.js"
},
"dependencies": {
"@storybook/node-logger": "5.2.0-beta.37",
"@storybook/router": "5.2.0-beta.37",
"@storybook/node-logger": "5.3.0-alpha.0",
"@storybook/router": "5.3.0-alpha.0",
"core-js": "^3.0.1",
"jest-image-snapshot": "^2.8.2",
"regenerator-runtime": "^0.12.1"

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/addon-storysource",
"version": "5.2.0-beta.37",
"version": "5.3.0-alpha.0",
"description": "Stories addon for storybook",
"keywords": [
"addon",
@ -28,11 +28,11 @@
"prepare": "node ../../scripts/prepare.js"
},
"dependencies": {
"@storybook/addons": "5.2.0-beta.37",
"@storybook/components": "5.2.0-beta.37",
"@storybook/router": "5.2.0-beta.37",
"@storybook/source-loader": "5.2.0-beta.37",
"@storybook/theming": "5.2.0-beta.37",
"@storybook/addons": "5.3.0-alpha.0",
"@storybook/components": "5.3.0-alpha.0",
"@storybook/router": "5.3.0-alpha.0",
"@storybook/source-loader": "5.3.0-alpha.0",
"@storybook/theming": "5.3.0-alpha.0",
"core-js": "^3.0.1",
"estraverse": "^4.2.0",
"loader-utils": "^1.2.3",

View File

@ -25,6 +25,7 @@ Then, add following content to .storybook/addons.js
```js
import '@storybook/addon-viewport/register';
```
You should now be able to see the viewport addon icon in the the toolbar at the top of the screen.
## Configuration
@ -34,7 +35,12 @@ The viewport addon is configured by story parameters with the `viewport` key. To
```js
import { addParameters } from '@storybook/react';
addParameters({ viewport: { viewports: newViewports } });
addParameters({
viewport: {
viewports: newViewports, // newViewports would be an ViewportMap. (see below for examples)
defaultViewport: 'someDefault',
},
});
```
Options can take a object with the following keys:
@ -49,7 +55,7 @@ Setting this property to, let say `iphone6`, will make `iPhone 6` the default de
---
A key-value pair of viewport's key and properties (see `Viewport` definition below) for all viewports to be displayed. Default is [`INITIAL_VIEWPORTS`](src/defaults.js)
A key-value pair of viewport's key and properties (see `Viewport` definition below) for all viewports to be displayed. Default is [`MINIMAL_VIEWPORTS`](src/defaults.ts)
#### Viewport Model
@ -95,6 +101,21 @@ addStories('Stories', module)
## Examples
### Use Detailed Set of Devices
The default viewports being used is [`MINIMAL_VIEWPORTS`](src/defaults.ts). If you'd like to use a more granular list of devices, you can use [`INITIAL_VIEWPORTS`](src/defaults.ts) like so in your `config.js` file in your `.storybook` directory.
```js
import { addParameters } from '@storybook/react';
import { INITIAL_VIEWPORTS } from '@storybook/addon-viewport';
addParameters({
viewport: {
viewports: INITIAL_VIEWPORTS,
},
});
```
### Use Custom Set of Devices
This will replace all previous devices with `Kindle Fire 2` and `Kindle Fire HD` by simply calling `addParameters` with the two devices as `viewports` in `config.js` file in your `.storybook` directory.
@ -126,7 +147,7 @@ addParameters({
### Add New Device
This will add both `Kindle Fire 2` and `Kindle Fire HD` to the list of devices. This is achieved by making use of the exported [`INITIAL_VIEWPORTS`](src/defaults.js) property, by merging it with the new viewports and pass the result as `viewports` to `configureViewport` function
This will add both `Kindle Fire 2` and `Kindle Fire HD` to the list of devices. This is achieved by making use of the exported [`INITIAL_VIEWPORTS`](src/defaults.ts) property, by merging it with the new viewports and pass the result as `viewports` to `configureViewport` function
```js
import { addParameters } from '@storybook/react';

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/addon-viewport",
"version": "5.2.0-beta.37",
"version": "5.3.0-alpha.0",
"description": "Storybook addon to change the viewport size to mobile",
"keywords": [
"addon",
@ -28,12 +28,12 @@
"prepare": "node ../../scripts/prepare.js"
},
"dependencies": {
"@storybook/addons": "5.2.0-beta.37",
"@storybook/api": "5.2.0-beta.37",
"@storybook/client-logger": "5.2.0-beta.37",
"@storybook/components": "5.2.0-beta.37",
"@storybook/core-events": "5.2.0-beta.37",
"@storybook/theming": "5.2.0-beta.37",
"@storybook/addons": "5.3.0-alpha.0",
"@storybook/api": "5.3.0-alpha.0",
"@storybook/client-logger": "5.3.0-alpha.0",
"@storybook/components": "5.3.0-alpha.0",
"@storybook/core-events": "5.3.0-alpha.0",
"@storybook/theming": "5.3.0-alpha.0",
"core-js": "^3.0.1",
"global": "^4.3.2",
"memoizerific": "^1.11.3",

View File

@ -8,6 +8,7 @@ import { Icons, IconButton, WithTooltip, TooltipLinkList } from '@storybook/comp
import { useParameter, useAddonState } from '@storybook/api';
import { PARAM_KEY, ADDON_ID } from './constants';
import { MINIMAL_VIEWPORTS } from './defaults';
import { ViewportAddonParameter, ViewportMap, ViewportStyles, Styles } from './models';
interface ViewportItem {
@ -70,7 +71,11 @@ interface Link extends LinkBase {
onClick: () => void;
}
const flip = ({ width, height }: ViewportStyles) => ({ height: width, width: height });
const flip = ({ width, height, ...styles }: ViewportStyles) => ({
...styles,
height: width,
width: height,
});
const ActiveViewportSize = styled.div(() => ({
display: 'inline-flex',
@ -122,7 +127,7 @@ export const ViewportTool: FunctionComponent<{}> = React.memo(
const { viewports, defaultViewport, disable } = useParameter<ViewportAddonParameter>(
PARAM_KEY,
{
viewports: {},
viewports: MINIMAL_VIEWPORTS,
defaultViewport: responsiveViewport.id,
}
);
@ -132,6 +137,14 @@ export const ViewportTool: FunctionComponent<{}> = React.memo(
});
const list = toList(viewports);
useEffect(() => {
setState({
selected:
defaultViewport || (viewports[state.selected] ? state.selected : responsiveViewport.id),
isRotated: state.isRotated,
});
}, [defaultViewport]);
const { selected, isRotated } = state;
const item =
list.find(i => i.id === selected) ||
@ -195,13 +208,15 @@ export const ViewportTool: FunctionComponent<{}> = React.memo(
},
[`#${wrapperId}`]: {
padding: theme.layoutMargin,
display: 'grid',
alignContent: 'center',
alignItems: 'center',
justifyContent: 'center',
justifyItems: 'center',
overflow: 'auto',
gridTemplateColumns: 'minmax(0, 1fr)',
display: 'grid',
gridTemplateColumns: '100%',
gridTemplateRows: '100%',
},
}}
/>

View File

@ -131,3 +131,30 @@ export const INITIAL_VIEWPORTS: ViewportMap = {
},
};
export const DEFAULT_VIEWPORT = 'responsive';
export const MINIMAL_VIEWPORTS: ViewportMap = {
mobile1: {
name: 'Small mobile',
styles: {
height: '568px',
width: '320px',
},
type: 'mobile',
},
mobile2: {
name: 'Large mobile',
styles: {
height: '896px',
width: '414px',
},
type: 'mobile',
},
tablet: {
name: 'Tablet',
styles: {
height: '1112px',
width: '834px',
},
type: 'tablet',
},
};

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/angular",
"version": "5.2.0-beta.37",
"version": "5.3.0-alpha.0",
"description": "Storybook for Angular: Develop Angular Components in isolation with Hot Reloading.",
"keywords": [
"storybook"
@ -34,9 +34,9 @@
"prepare": "node ../../scripts/prepare.js"
},
"dependencies": {
"@storybook/addons": "5.2.0-beta.37",
"@storybook/core": "5.2.0-beta.37",
"@storybook/node-logger": "5.2.0-beta.37",
"@storybook/addons": "5.3.0-alpha.0",
"@storybook/core": "5.3.0-alpha.0",
"@storybook/node-logger": "5.3.0-alpha.0",
"angular2-template-loader": "^0.6.2",
"core-js": "^3.0.1",
"fork-ts-checker-webpack-plugin": "^1.3.4",

View File

@ -3,7 +3,7 @@
"compileOnSave": false,
"compilerOptions": {
"outDir": "dist",
"types": ["webpack-env"],
"types": [],
"rootDir": "./src",
"resolveJsonModule": true
}

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/ember",
"version": "5.2.0-beta.37",
"version": "5.3.0-alpha.0",
"description": "Storybook for Ember: Develop Ember Component in isolation with Hot Reloading.",
"homepage": "https://github.com/storybookjs/storybook/tree/master/app/ember",
"bugs": {
@ -30,7 +30,7 @@
},
"dependencies": {
"@ember/test-helpers": "^1.5.0",
"@storybook/core": "5.2.0-beta.37",
"@storybook/core": "5.3.0-alpha.0",
"common-tags": "^1.8.0",
"core-js": "^3.0.1",
"global": "^4.3.2",

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/html",
"version": "5.2.0-beta.37",
"version": "5.3.0-alpha.0",
"description": "Storybook for HTML: View HTML snippets in isolation with Hot Reloading.",
"keywords": [
"storybook"
@ -32,8 +32,8 @@
"prepare": "node ../../scripts/prepare.js"
},
"dependencies": {
"@storybook/addons": "5.2.0-beta.37",
"@storybook/core": "5.2.0-beta.37",
"@storybook/addons": "5.3.0-alpha.0",
"@storybook/core": "5.3.0-alpha.0",
"common-tags": "^1.8.0",
"core-js": "^3.0.1",
"global": "^4.3.2",

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/marko",
"version": "5.2.0-beta.37",
"version": "5.3.0-alpha.0",
"description": "Storybook for Marko: Develop Marko Component in isolation with Hot Reloading.",
"keywords": [
"storybook"
@ -32,8 +32,8 @@
},
"dependencies": {
"@marko/webpack": "^1.2.0",
"@storybook/client-logger": "5.2.0-beta.37",
"@storybook/core": "5.2.0-beta.37",
"@storybook/client-logger": "5.3.0-alpha.0",
"@storybook/core": "5.3.0-alpha.0",
"common-tags": "^1.8.0",
"core-js": "^3.0.1",
"global": "^4.3.2",

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/mithril",
"version": "5.2.0-beta.37",
"version": "5.3.0-alpha.0",
"description": "Storybook for Mithril: Develop Mithril Component in isolation.",
"keywords": [
"storybook"
@ -32,7 +32,7 @@
},
"dependencies": {
"@babel/plugin-transform-react-jsx": "^7.3.0",
"@storybook/core": "5.2.0-beta.37",
"@storybook/core": "5.3.0-alpha.0",
"common-tags": "^1.8.0",
"core-js": "^3.0.1",
"global": "^4.3.2",

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/polymer",
"version": "5.2.0-beta.37",
"version": "5.3.0-alpha.0",
"description": "Storybook for Polymer: Develop Polymer components in isolation with Hot Reloading.",
"keywords": [
"storybook"
@ -31,7 +31,7 @@
"prepare": "node ../../scripts/prepare.js"
},
"dependencies": {
"@storybook/core": "5.2.0-beta.37",
"@storybook/core": "5.3.0-alpha.0",
"@webcomponents/webcomponentsjs": "^1.2.0",
"common-tags": "^1.8.0",
"core-js": "^3.0.1",

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/preact",
"version": "5.2.0-beta.37",
"version": "5.3.0-alpha.0",
"description": "Storybook for Preact: Develop Preact Component in isolation.",
"keywords": [
"storybook"
@ -33,8 +33,8 @@
},
"dependencies": {
"@babel/plugin-transform-react-jsx": "^7.3.0",
"@storybook/addons": "5.2.0-beta.37",
"@storybook/core": "5.2.0-beta.37",
"@storybook/addons": "5.3.0-alpha.0",
"@storybook/core": "5.3.0-alpha.0",
"common-tags": "^1.8.0",
"core-js": "^3.0.1",
"global": "^4.3.2",

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/rax",
"version": "5.2.0-beta.37",
"version": "5.3.0-alpha.0",
"description": "Storybook for Rax: Develop Rax Component in isolation.",
"keywords": [
"rax",
@ -32,7 +32,7 @@
"prepare": "node ../../scripts/prepare.js"
},
"dependencies": {
"@storybook/core": "5.2.0-beta.37",
"@storybook/core": "5.3.0-alpha.0",
"babel-preset-rax": "^1.0.0-beta.0",
"common-tags": "^1.8.0",
"core-js": "^2.6.2",

Some files were not shown because too many files have changed in this diff Show More