Merge branch 'future/base' into future/drop-emotion-10-types

# Conflicts:
#	lib/blocks/src/blocks/DocsContainer.tsx
#	lib/blocks/src/blocks/SourceContainer.tsx
#	lib/blocks/src/blocks/Subtitle.tsx
#	lib/blocks/src/blocks/Title.tsx
#	lib/blocks/src/components/ColorPalette.tsx
#	lib/blocks/src/components/IconGallery.tsx
#	lib/blocks/src/components/Source.tsx
#	lib/blocks/src/components/Story.tsx
#	lib/components/src/placeholder/placeholder.tsx
#	lib/ui/src/components/preview/toolbar.tsx
#	lib/ui/src/components/preview/utils/types.tsx
#	lib/ui/src/components/sidebar/Sidebar.tsx
#	lib/ui/src/components/sidebar/TreeNode.tsx
This commit is contained in:
Norbert de Langen 2022-07-19 09:58:12 +02:00
commit 057c40124d
No known key found for this signature in database
GPG Key ID: FD0E78AF9A837762
921 changed files with 12900 additions and 10911 deletions

View File

@ -223,27 +223,30 @@ jobs:
- store_artifacts:
path: /tmp/storybook-e2e-testing-out.zip
destination: e2e
e2e-tests-sb-docs:
executor:
class: large
name: sb_cypress_8_node_14
parallelism: 2
steps:
- git-shallow-clone/checkout_advanced:
clone_options: '--depth 1 --verbose'
- attach_workspace:
at: .
- run:
name: Running local registry
command: yarn local-registry --port 6000 --open
background: true
- run:
name: Wait for registry
command: yarn wait-on http://localhost:6000
- run:
name: Run smoke tests
command: yarn test:e2e-framework angular_modern_inline_rendering --test-runner --docs-mode
no_output_timeout: 5m
# NOTE: this currently tests each story in docs mode, which doesn't make sense any more as stories
# can no longer run in docs mode. Instead we should probably change the test runner to test each
# docs entry if you run it in `VIEW_MODE=docs`
# e2e-tests-sb-docs:
# executor:
# class: large
# name: sb_cypress_8_node_14
# parallelism: 2
# steps:
# - git-shallow-clone/checkout_advanced:
# clone_options: '--depth 1 --verbose'
# - attach_workspace:
# at: .
# - run:
# name: Running local registry
# command: yarn local-registry --port 6000 --open
# background: true
# - run:
# name: Wait for registry
# command: yarn wait-on http://localhost:6000
# - run:
# name: Run smoke tests
# command: yarn test:e2e-framework angular_modern_inline_rendering --test-runner --docs-mode
# no_output_timeout: 5m
cra-bench:
executor:
class: medium
@ -420,9 +423,6 @@ workflows:
- e2e-tests-core:
requires:
- publish
- e2e-tests-sb-docs:
requires:
- publish
- e2e-tests-pnp:
requires:
- publish

View File

@ -1,3 +1,59 @@
## 7.0.0-alpha.13 (July 11, 2022)
### Features
- UI: Remove docs tab ([#18677](https://github.com/storybookjs/storybook/pull/18677))
### Bug Fixes
- Index: Don't prepend `titlePrefix` to a docs entry that references a CSF file's title ([#18634](https://github.com/storybookjs/storybook/pull/18634))
### Maintenance
- Addon-dcos: Refactor DocsRender/Context ([#18635](https://github.com/storybookjs/storybook/pull/18635))
- Instrumenter: `SyncPayload` type for `sync` event ([#18674](https://github.com/storybookjs/storybook/pull/18674))
## 7.0.0-alpha.12 (July 7, 2022)
### Features
- Addon-docs: Produce docs page entries in the index ([#18574](https://github.com/storybookjs/storybook/pull/18574))
- Svelte: Supports action auto configuration ([#18174](https://github.com/storybookjs/storybook/pull/18174))
- Addon-docs: Add docs index configuration via main.js ([#18573](https://github.com/storybookjs/storybook/pull/18573))
- Preview: Handle new docs-page index entries ([#18595](https://github.com/storybookjs/storybook/pull/18595))
### Bug Fixes
- CLI: Remove addon-actions install from `sb init` ([#18255](https://github.com/storybookjs/storybook/pull/18255))
- Angular: Fix compodoc with spaces in workspace root ([#18140](https://github.com/storybookjs/storybook/pull/18140))
- Core: Add type guard for globalWindow ([#18251](https://github.com/storybookjs/storybook/pull/18251))
- Core: Fix builder stats typings to be optional ([#18377](https://github.com/storybookjs/storybook/pull/18377))
### Maintenance
- Core: Async load presets, replace interpret with esbuild-register ([#18619](https://github.com/storybookjs/storybook/pull/18619))
- Build: Improve linting a bit ([#18642](https://github.com/storybookjs/storybook/pull/18642))
### Dependency Upgrades
- Deps: Use `dequal` for equality checks ([#18608](https://github.com/storybookjs/storybook/pull/18608))
## 7.0.0-alpha.11 (July 6, 2022)
### Features
- Interactions: Show exceptions by non-instrumented code in panel ([#16592](https://github.com/storybookjs/storybook/pull/16592))
### Maintenance
- Build: Add linter for ejs ([#18637](https://github.com/storybookjs/storybook/pull/18637))
- Core: Improve interopRequireDefault ([#18638](https://github.com/storybookjs/storybook/pull/18638))
- Core: Pre-built manager using esbuild ([#18550](https://github.com/storybookjs/storybook/pull/18550))
- Build: Add check-packages script plus misc improvements ([#18633](https://github.com/storybookjs/storybook/pull/18633))
- Core: Typing useArgs ([#17735](https://github.com/storybookjs/storybook/pull/17735))
- Build: Add a check script to each package ([#18603](https://github.com/storybookjs/storybook/pull/18603))
- Build: Use playwright in benchmark ([#18606](https://github.com/storybookjs/storybook/pull/18606))
## 7.0.0-alpha.10 (July 2, 2022)
### Features

View File

@ -13,6 +13,7 @@
- [Docs modern inline rendering by default](#docs-modern-inline-rendering-by-default)
- [Babel mode v7 by default](#babel-mode-v7-by-default)
- [7.0 feature flags removed](#70-feature-flags-removed)
- [Removed docs.getContainer and getPage parameters](#removed-docs-getcontainer-and-getpage-parameters)
- [From version 6.4.x to 6.5.0](#from-version-64x-to-650)
- [Vue 3 upgrade](#vue-3-upgrade)
- [React18 new root API](#react18-new-root-api)
@ -393,6 +394,10 @@ In 7.0 we've removed the following feature flags:
| `emotionAlias` | This flag is no longer needed and should be deleted. |
| `breakingChangesV7` | This flag is no longer needed and should be deleted. |
#### Removed docs.getContainer and getPage parameters
It is no longer possible to set `parameters.docs.getContainer()` and `getPage()`. Instead use `parameters.docs.container` or `parameters.docs.page` directly.
## From version 6.4.x to 6.5.0
### Vue 3 upgrade

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/addon-a11y",
"version": "7.0.0-alpha.10",
"version": "7.0.0-alpha.13",
"description": "Test component compliance with web accessibility standards",
"keywords": [
"a11y",
@ -39,15 +39,15 @@
"prepare": "node ../../scripts/prepare.js"
},
"dependencies": {
"@storybook/addon-highlight": "7.0.0-alpha.10",
"@storybook/addons": "7.0.0-alpha.10",
"@storybook/api": "7.0.0-alpha.10",
"@storybook/channels": "7.0.0-alpha.10",
"@storybook/client-logger": "7.0.0-alpha.10",
"@storybook/components": "7.0.0-alpha.10",
"@storybook/core-events": "7.0.0-alpha.10",
"@storybook/addon-highlight": "7.0.0-alpha.13",
"@storybook/addons": "7.0.0-alpha.13",
"@storybook/api": "7.0.0-alpha.13",
"@storybook/channels": "7.0.0-alpha.13",
"@storybook/client-logger": "7.0.0-alpha.13",
"@storybook/components": "7.0.0-alpha.13",
"@storybook/core-events": "7.0.0-alpha.13",
"@storybook/csf": "0.0.2--canary.4566f4d.1",
"@storybook/theming": "7.0.0-alpha.10",
"@storybook/theming": "7.0.0-alpha.13",
"axe-core": "^4.2.0",
"core-js": "^3.8.2",
"global": "^4.4.0",
@ -75,7 +75,7 @@
"publishConfig": {
"access": "public"
},
"gitHead": "b13dd8fb52819d73d4983148af8ffc5d683e8b75",
"gitHead": "9ac4d2e0a05eb945713a0e6689abc3b12359e181",
"storybook": {
"displayName": "Accessibility",
"icon": "https://user-images.githubusercontent.com/263385/101991665-47042f80-3c7c-11eb-8f00-64b5a18f498a.png",

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/addon-actions",
"version": "7.0.0-alpha.10",
"version": "7.0.0-alpha.13",
"description": "Get UI feedback when an action is performed on an interactive element",
"keywords": [
"storybook",
@ -35,15 +35,15 @@
"prepare": "node ../../scripts/prepare.js"
},
"dependencies": {
"@storybook/addons": "7.0.0-alpha.10",
"@storybook/api": "7.0.0-alpha.10",
"@storybook/client-logger": "7.0.0-alpha.10",
"@storybook/components": "7.0.0-alpha.10",
"@storybook/core-events": "7.0.0-alpha.10",
"@storybook/addons": "7.0.0-alpha.13",
"@storybook/api": "7.0.0-alpha.13",
"@storybook/client-logger": "7.0.0-alpha.13",
"@storybook/components": "7.0.0-alpha.13",
"@storybook/core-events": "7.0.0-alpha.13",
"@storybook/csf": "0.0.2--canary.4566f4d.1",
"@storybook/theming": "7.0.0-alpha.10",
"@storybook/theming": "7.0.0-alpha.13",
"core-js": "^3.8.2",
"fast-deep-equal": "^3.1.3",
"dequal": "^2.0.2",
"global": "^4.4.0",
"lodash": "^4.17.21",
"polished": "^4.2.2",
@ -73,7 +73,7 @@
"publishConfig": {
"access": "public"
},
"gitHead": "b13dd8fb52819d73d4983148af8ffc5d683e8b75",
"gitHead": "9ac4d2e0a05eb945713a0e6689abc3b12359e181",
"storybook": {
"displayName": "Actions",
"unsupportedFrameworks": [

View File

@ -1,5 +1,5 @@
import React, { Component } from 'react';
import deepEqual from 'fast-deep-equal';
import { dequal as deepEqual } from 'dequal';
import type { API } from '@storybook/api';
import { STORY_CHANGED } from '@storybook/core-events';

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/addon-backgrounds",
"version": "7.0.0-alpha.10",
"version": "7.0.0-alpha.13",
"description": "Switch backgrounds to view components in different settings",
"keywords": [
"addon",
@ -39,13 +39,13 @@
"prepare": "node ../../scripts/prepare.js"
},
"dependencies": {
"@storybook/addons": "7.0.0-alpha.10",
"@storybook/api": "7.0.0-alpha.10",
"@storybook/client-logger": "7.0.0-alpha.10",
"@storybook/components": "7.0.0-alpha.10",
"@storybook/core-events": "7.0.0-alpha.10",
"@storybook/addons": "7.0.0-alpha.13",
"@storybook/api": "7.0.0-alpha.13",
"@storybook/client-logger": "7.0.0-alpha.13",
"@storybook/components": "7.0.0-alpha.13",
"@storybook/core-events": "7.0.0-alpha.13",
"@storybook/csf": "0.0.2--canary.4566f4d.1",
"@storybook/theming": "7.0.0-alpha.10",
"@storybook/theming": "7.0.0-alpha.13",
"core-js": "^3.8.2",
"global": "^4.4.0",
"memoizerific": "^1.11.3",
@ -70,7 +70,7 @@
"publishConfig": {
"access": "public"
},
"gitHead": "b13dd8fb52819d73d4983148af8ffc5d683e8b75",
"gitHead": "9ac4d2e0a05eb945713a0e6689abc3b12359e181",
"storybook": {
"displayName": "Backgrounds",
"icon": "https://user-images.githubusercontent.com/263385/101991667-479cc600-3c7c-11eb-96d3-410e936252e7.png",

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/addon-controls",
"version": "7.0.0-alpha.10",
"version": "7.0.0-alpha.13",
"description": "Interact with component inputs dynamically in the Storybook UI",
"keywords": [
"addon",
@ -39,16 +39,16 @@
"prepare": "node ../../scripts/prepare.js"
},
"dependencies": {
"@storybook/addons": "7.0.0-alpha.10",
"@storybook/api": "7.0.0-alpha.10",
"@storybook/blocks": "7.0.0-alpha.10",
"@storybook/client-logger": "7.0.0-alpha.10",
"@storybook/components": "7.0.0-alpha.10",
"@storybook/core-common": "7.0.0-alpha.10",
"@storybook/addons": "7.0.0-alpha.13",
"@storybook/api": "7.0.0-alpha.13",
"@storybook/blocks": "7.0.0-alpha.13",
"@storybook/client-logger": "7.0.0-alpha.13",
"@storybook/components": "7.0.0-alpha.13",
"@storybook/core-common": "7.0.0-alpha.13",
"@storybook/csf": "0.0.2--canary.4566f4d.1",
"@storybook/node-logger": "7.0.0-alpha.10",
"@storybook/store": "7.0.0-alpha.10",
"@storybook/theming": "7.0.0-alpha.10",
"@storybook/node-logger": "7.0.0-alpha.13",
"@storybook/store": "7.0.0-alpha.13",
"@storybook/theming": "7.0.0-alpha.13",
"core-js": "^3.8.2",
"lodash": "^4.17.21",
"ts-dedent": "^2.0.0"
@ -68,7 +68,7 @@
"publishConfig": {
"access": "public"
},
"gitHead": "b13dd8fb52819d73d4983148af8ffc5d683e8b75",
"gitHead": "9ac4d2e0a05eb945713a0e6689abc3b12359e181",
"storybook": {
"displayName": "Controls",
"icon": "https://user-images.githubusercontent.com/263385/101991669-479cc600-3c7c-11eb-93d9-38b67e8371f2.png",

View File

@ -1 +0,0 @@
import './dist/esm/manager';

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/addon-docs",
"version": "7.0.0-alpha.10",
"version": "7.0.0-alpha.13",
"description": "Document component usage and properties in Markdown",
"keywords": [
"addon",
@ -53,25 +53,25 @@
"@babel/preset-env": "^7.12.11",
"@jest/transform": "^26.6.2",
"@mdx-js/react": "^1.6.22",
"@storybook/addons": "7.0.0-alpha.10",
"@storybook/api": "7.0.0-alpha.10",
"@storybook/blocks": "7.0.0-alpha.10",
"@storybook/components": "7.0.0-alpha.10",
"@storybook/core-common": "7.0.0-alpha.10",
"@storybook/core-events": "7.0.0-alpha.10",
"@storybook/addons": "7.0.0-alpha.13",
"@storybook/api": "7.0.0-alpha.13",
"@storybook/blocks": "7.0.0-alpha.13",
"@storybook/components": "7.0.0-alpha.13",
"@storybook/core-common": "7.0.0-alpha.13",
"@storybook/core-events": "7.0.0-alpha.13",
"@storybook/csf": "0.0.2--canary.4566f4d.1",
"@storybook/csf-tools": "7.0.0-alpha.10",
"@storybook/docs-tools": "7.0.0-alpha.10",
"@storybook/mdx1-csf": "^0.0.1",
"@storybook/node-logger": "7.0.0-alpha.10",
"@storybook/postinstall": "7.0.0-alpha.10",
"@storybook/preview-web": "7.0.0-alpha.10",
"@storybook/source-loader": "7.0.0-alpha.10",
"@storybook/store": "7.0.0-alpha.10",
"@storybook/theming": "7.0.0-alpha.10",
"@storybook/csf-tools": "7.0.0-alpha.13",
"@storybook/docs-tools": "7.0.0-alpha.13",
"@storybook/mdx1-csf": "0.0.5-canary.13.9ce928a.0",
"@storybook/node-logger": "7.0.0-alpha.13",
"@storybook/postinstall": "7.0.0-alpha.13",
"@storybook/preview-web": "7.0.0-alpha.13",
"@storybook/source-loader": "7.0.0-alpha.13",
"@storybook/store": "7.0.0-alpha.13",
"@storybook/theming": "7.0.0-alpha.13",
"babel-loader": "^8.2.5",
"core-js": "^3.8.2",
"fast-deep-equal": "^3.1.3",
"dequal": "^2.0.2",
"global": "^4.4.0",
"lodash": "^4.17.21",
"remark-external-links": "^8.0.0",
@ -81,12 +81,12 @@
},
"devDependencies": {
"@babel/core": "^7.12.10",
"@storybook/mdx2-csf": "^0.0.3",
"@storybook/mdx2-csf": "0.0.4-canary.14.04ffbe8.0",
"@types/util-deprecate": "^1.0.0",
"typescript": "~4.6.3"
},
"peerDependencies": {
"@storybook/mdx2-csf": "^0.0.3",
"@storybook/mdx2-csf": "0.0.4-canary.14.04ffbe8.0",
"react": "^16.8.0 || ^17.0.0 || ^18.0.0",
"react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0"
},
@ -104,7 +104,7 @@
"publishConfig": {
"access": "public"
},
"gitHead": "b13dd8fb52819d73d4983148af8ffc5d683e8b75",
"gitHead": "9ac4d2e0a05eb945713a0e6689abc3b12359e181",
"storybook": {
"displayName": "Docs",
"icon": "https://user-images.githubusercontent.com/263385/101991672-48355c80-3c7c-11eb-82d9-95fa12438f64.png",

View File

@ -1,6 +0,0 @@
import { once } from '@storybook/client-logger';
import './manager';
once.warn(
'register.js is deprecated see https://github.com/storybookjs/storybook/blob/next/MIGRATION.md#deprecated-registerjs'
);

View File

@ -0,0 +1,45 @@
import React from 'react';
import ReactDOM from 'react-dom';
import { AnyFramework, Parameters } from '@storybook/csf';
import { DocsContextProps, DocsRenderFunction } from '@storybook/preview-web';
import { components as htmlComponents } from '@storybook/components';
import { Docs, CodeOrSourceMdx, AnchorMdx, HeadersMdx } from '@storybook/blocks';
import { MDXProvider } from '@mdx-js/react';
// TS doesn't like that we export a component with types that it doesn't know about (TS4203)
export const defaultComponents: Record<string, any> = {
...htmlComponents,
code: CodeOrSourceMdx,
a: AnchorMdx,
...HeadersMdx,
};
export class DocsRenderer<TFramework extends AnyFramework> {
public render: DocsRenderFunction<TFramework>;
public unmount: (element: HTMLElement) => void;
constructor() {
this.render = (
context: DocsContextProps<TFramework>,
docsParameter: Parameters,
element: HTMLElement,
callback: () => void
): void => {
// Use a random key to force the container to re-render each time we call `renderDocs`
// TODO: do we still need this? It was needed for angular (legacy) inline rendering:
// https://github.com/storybookjs/storybook/pull/16149
ReactDOM.render(
<MDXProvider components={defaultComponents}>
<Docs key={Math.random()} context={context} docsParameter={docsParameter} />
</MDXProvider>,
element,
callback
);
};
this.unmount = (element: HTMLElement) => {
ReactDOM.unmountComponentAtNode(element);
};
}
}

View File

@ -1 +1,2 @@
export * from './blocks';
export { DocsRenderer } from './DocsRenderer';

View File

@ -1,12 +0,0 @@
import { addons, types } from '@storybook/addons';
import { ADDON_ID, PANEL_ID } from './shared';
addons.register(ADDON_ID, () => {
addons.add(PANEL_ID, {
type: types.TAB,
title: 'Docs',
route: ({ storyId, refId }) => (refId ? `/docs/${refId}_${storyId}` : `/docs/${storyId}`),
match: ({ viewMode }) => viewMode === 'docs',
render: () => null,
});
});

View File

@ -3,7 +3,7 @@ import remarkSlug from 'remark-slug';
import remarkExternalLinks from 'remark-external-links';
import global from 'global';
import type { IndexerOptions, Options, StoryIndexer } from '@storybook/core-common';
import type { DocsOptions, IndexerOptions, Options, StoryIndexer } from '@storybook/core-common';
import { logger } from '@storybook/node-logger';
import { loadCsf } from '@storybook/csf-tools';
@ -137,7 +137,7 @@ export async function webpack(
return result;
}
export const storyIndexers = async (indexers?: StoryIndexer[]) => {
export const storyIndexers = async (indexers: StoryIndexer[] | null) => {
const mdxIndexer = async (fileName: string, opts: IndexerOptions) => {
let code = (await fs.readFile(fileName, 'utf-8')).toString();
// @ts-ignore
@ -151,7 +151,17 @@ export const storyIndexers = async (indexers?: StoryIndexer[]) => {
{
test: /(stories|story)\.mdx$/,
indexer: mdxIndexer,
addDocsTemplate: true,
},
...(indexers || []),
];
};
export const docs = (docsOptions: DocsOptions) => {
return {
...docsOptions,
enabled: true,
defaultName: 'Docs',
docsPage: true,
};
};

View File

@ -1,7 +1,7 @@
export const parameters: any = {
docs: {
renderer: async () => {
const { DocsRenderer } = (await import('./blocks')) as any;
const { DocsRenderer } = (await import('./DocsRenderer')) as any;
return new DocsRenderer();
},
},

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/addon-essentials",
"version": "7.0.0-alpha.10",
"version": "7.0.0-alpha.13",
"description": "Curated addons to bring out the best of Storybook",
"keywords": [
"addon",
@ -33,25 +33,25 @@
"prepare": "node ../../scripts/prepare.js"
},
"dependencies": {
"@storybook/addon-actions": "7.0.0-alpha.10",
"@storybook/addon-backgrounds": "7.0.0-alpha.10",
"@storybook/addon-controls": "7.0.0-alpha.10",
"@storybook/addon-docs": "7.0.0-alpha.10",
"@storybook/addon-highlight": "7.0.0-alpha.10",
"@storybook/addon-measure": "7.0.0-alpha.10",
"@storybook/addon-outline": "7.0.0-alpha.10",
"@storybook/addon-toolbars": "7.0.0-alpha.10",
"@storybook/addon-viewport": "7.0.0-alpha.10",
"@storybook/addons": "7.0.0-alpha.10",
"@storybook/api": "7.0.0-alpha.10",
"@storybook/core-common": "7.0.0-alpha.10",
"@storybook/node-logger": "7.0.0-alpha.10",
"@storybook/addon-actions": "7.0.0-alpha.13",
"@storybook/addon-backgrounds": "7.0.0-alpha.13",
"@storybook/addon-controls": "7.0.0-alpha.13",
"@storybook/addon-docs": "7.0.0-alpha.13",
"@storybook/addon-highlight": "7.0.0-alpha.13",
"@storybook/addon-measure": "7.0.0-alpha.13",
"@storybook/addon-outline": "7.0.0-alpha.13",
"@storybook/addon-toolbars": "7.0.0-alpha.13",
"@storybook/addon-viewport": "7.0.0-alpha.13",
"@storybook/addons": "7.0.0-alpha.13",
"@storybook/api": "7.0.0-alpha.13",
"@storybook/core-common": "7.0.0-alpha.13",
"@storybook/node-logger": "7.0.0-alpha.13",
"core-js": "^3.8.2",
"ts-dedent": "^2.0.0"
},
"devDependencies": {
"@babel/core": "^7.12.10",
"@storybook/vue": "7.0.0-alpha.10",
"@storybook/vue": "7.0.0-alpha.13",
"@types/jest": "^26.0.16",
"typescript": "~4.6.3"
},
@ -99,5 +99,5 @@
"publishConfig": {
"access": "public"
},
"gitHead": "b13dd8fb52819d73d4983148af8ffc5d683e8b75"
"gitHead": "9ac4d2e0a05eb945713a0e6689abc3b12359e181"
}

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/addon-highlight",
"version": "7.0.0-alpha.10",
"version": "7.0.0-alpha.13",
"description": "Highlight DOM nodes within your stories",
"keywords": [
"storybook-addons",
@ -37,8 +37,8 @@
"prepare": "node ../../scripts/prepare.js"
},
"dependencies": {
"@storybook/addons": "7.0.0-alpha.10",
"@storybook/core-events": "7.0.0-alpha.10",
"@storybook/addons": "7.0.0-alpha.13",
"@storybook/core-events": "7.0.0-alpha.13",
"core-js": "^3.8.2",
"global": "^4.4.0"
},
@ -49,7 +49,7 @@
"publishConfig": {
"access": "public"
},
"gitHead": "b13dd8fb52819d73d4983148af8ffc5d683e8b75",
"gitHead": "9ac4d2e0a05eb945713a0e6689abc3b12359e181",
"sbmodern": "dist/modern/index.js",
"storybook": {
"displayName": "Highlight",

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/addon-interactions",
"version": "7.0.0-alpha.10",
"version": "7.0.0-alpha.13",
"description": "Automate, test and debug user interactions",
"keywords": [
"storybook-addons",
@ -36,15 +36,15 @@
},
"dependencies": {
"@devtools-ds/object-inspector": "^1.1.2",
"@storybook/addons": "7.0.0-alpha.10",
"@storybook/api": "7.0.0-alpha.10",
"@storybook/client-logger": "7.0.0-alpha.10",
"@storybook/components": "7.0.0-alpha.10",
"@storybook/core-common": "7.0.0-alpha.10",
"@storybook/core-events": "7.0.0-alpha.10",
"@storybook/addons": "7.0.0-alpha.13",
"@storybook/api": "7.0.0-alpha.13",
"@storybook/client-logger": "7.0.0-alpha.13",
"@storybook/components": "7.0.0-alpha.13",
"@storybook/core-common": "7.0.0-alpha.13",
"@storybook/core-events": "7.0.0-alpha.13",
"@storybook/csf": "0.0.2--canary.4566f4d.1",
"@storybook/instrumenter": "7.0.0-alpha.10",
"@storybook/theming": "7.0.0-alpha.10",
"@storybook/instrumenter": "7.0.0-alpha.13",
"@storybook/theming": "7.0.0-alpha.13",
"core-js": "^3.8.2",
"global": "^4.4.0",
"jest-mock": "^27.0.6",
@ -52,7 +52,7 @@
"ts-dedent": "^2.2.0"
},
"devDependencies": {
"@storybook/jest": "^0.0.5",
"@storybook/jest": "^0.0.10",
"@storybook/testing-library": "0.0.14-next.0",
"formik": "^2.2.9",
"typescript": "~4.6.3"
@ -72,7 +72,7 @@
"publishConfig": {
"access": "public"
},
"gitHead": "b13dd8fb52819d73d4983148af8ffc5d683e8b75",
"gitHead": "9ac4d2e0a05eb945713a0e6689abc3b12359e181",
"storybook": {
"displayName": "Interactions",
"unsupportedFrameworks": [

View File

@ -84,7 +84,7 @@ WaitForElementToBeRemoved.play = async ({ canvasElement }) => {
const canvas = within(canvasElement);
await waitForElementToBeRemoved(await canvas.findByText('Loading...'), { timeout: 2000 });
const button = await canvas.findByText('Loaded!');
await expect(button).not.toBeNull();
await expect(button).toBeInTheDocument();
};
export const WithLoaders: CSF2Story = (args, { loaded: { todo } }) => {

View File

@ -62,6 +62,6 @@ export const Hovered: Story = {
play: async ({ canvasElement }) => {
const canvas = within(canvasElement);
await userEvent.hover(canvas.getByRole('button'));
await expect(canvas.getByTestId('icon-active')).not.toBeNull();
await expect(canvas.getByTestId('icon-active')).toBeInTheDocument();
},
};

View File

@ -6,6 +6,7 @@ import { CallStates } from '@storybook/instrumenter';
import { styled } from '@storybook/theming';
import { userEvent, within, waitFor } from '@storybook/testing-library';
import { expect } from '@storybook/jest';
import isChromatic from 'chromatic/isChromatic';
import { getCalls, getInteractions } from '../mocks';
import { InteractionsPanel } from './InteractionsPanel';
@ -62,6 +63,7 @@ export const Passing: Story = {
},
};
Passing.play = async ({ args, canvasElement }) => {
if (isChromatic()) return;
const canvas = within(canvasElement);
await waitFor(async () => {

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/addon-jest",
"version": "7.0.0-alpha.10",
"version": "7.0.0-alpha.13",
"description": "React storybook addon that show component jest report",
"keywords": [
"addon",
@ -41,12 +41,12 @@
"prepare": "node ../../scripts/prepare.js"
},
"dependencies": {
"@storybook/addons": "7.0.0-alpha.10",
"@storybook/api": "7.0.0-alpha.10",
"@storybook/client-logger": "7.0.0-alpha.10",
"@storybook/components": "7.0.0-alpha.10",
"@storybook/core-events": "7.0.0-alpha.10",
"@storybook/theming": "7.0.0-alpha.10",
"@storybook/addons": "7.0.0-alpha.13",
"@storybook/api": "7.0.0-alpha.13",
"@storybook/client-logger": "7.0.0-alpha.13",
"@storybook/components": "7.0.0-alpha.13",
"@storybook/core-events": "7.0.0-alpha.13",
"@storybook/theming": "7.0.0-alpha.13",
"core-js": "^3.8.2",
"global": "^4.4.0",
"react-sizeme": "^3.0.1",
@ -70,7 +70,7 @@
"publishConfig": {
"access": "public"
},
"gitHead": "b13dd8fb52819d73d4983148af8ffc5d683e8b75",
"gitHead": "9ac4d2e0a05eb945713a0e6689abc3b12359e181",
"storybook": {
"displayName": "Jest",
"icon": "https://pbs.twimg.com/profile_images/821713465245102080/mMtKIMax_400x400.jpg",

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/addon-links",
"version": "7.0.0-alpha.10",
"version": "7.0.0-alpha.13",
"description": "Link stories together to build demos and prototypes with your UI components",
"keywords": [
"addon",
@ -35,11 +35,11 @@
"prepare": "node ../../scripts/prepare.js"
},
"dependencies": {
"@storybook/addons": "7.0.0-alpha.10",
"@storybook/client-logger": "7.0.0-alpha.10",
"@storybook/core-events": "7.0.0-alpha.10",
"@storybook/addons": "7.0.0-alpha.13",
"@storybook/client-logger": "7.0.0-alpha.13",
"@storybook/core-events": "7.0.0-alpha.13",
"@storybook/csf": "0.0.2--canary.4566f4d.1",
"@storybook/router": "7.0.0-alpha.10",
"@storybook/router": "7.0.0-alpha.13",
"core-js": "^3.8.2",
"global": "^4.4.0",
"prop-types": "^15.7.2",
@ -63,7 +63,7 @@
"publishConfig": {
"access": "public"
},
"gitHead": "b13dd8fb52819d73d4983148af8ffc5d683e8b75",
"gitHead": "9ac4d2e0a05eb945713a0e6689abc3b12359e181",
"storybook": {
"displayName": "Links",
"icon": "https://user-images.githubusercontent.com/263385/101991673-48355c80-3c7c-11eb-9b6e-b627c96a75f6.png",

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/addon-measure",
"version": "7.0.0-alpha.10",
"version": "7.0.0-alpha.13",
"description": "Inspect layouts by visualizing the box model",
"keywords": [
"storybook-addons",
@ -38,11 +38,11 @@
"prepare": "node ../../scripts/prepare.js"
},
"dependencies": {
"@storybook/addons": "7.0.0-alpha.10",
"@storybook/api": "7.0.0-alpha.10",
"@storybook/client-logger": "7.0.0-alpha.10",
"@storybook/components": "7.0.0-alpha.10",
"@storybook/core-events": "7.0.0-alpha.10",
"@storybook/addons": "7.0.0-alpha.13",
"@storybook/api": "7.0.0-alpha.13",
"@storybook/client-logger": "7.0.0-alpha.13",
"@storybook/components": "7.0.0-alpha.13",
"@storybook/core-events": "7.0.0-alpha.13",
"@storybook/csf": "0.0.2--canary.4566f4d.1",
"core-js": "^3.8.2",
"global": "^4.4.0"
@ -65,7 +65,7 @@
"publishConfig": {
"access": "public"
},
"gitHead": "b13dd8fb52819d73d4983148af8ffc5d683e8b75",
"gitHead": "9ac4d2e0a05eb945713a0e6689abc3b12359e181",
"storybook": {
"displayName": "Measure",
"unsupportedFrameworks": [

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/addon-outline",
"version": "7.0.0-alpha.10",
"version": "7.0.0-alpha.13",
"description": "Outline all elements with CSS to help with layout placement and alignment",
"keywords": [
"storybook-addons",
@ -41,11 +41,11 @@
"prepare": "node ../../scripts/prepare.js"
},
"dependencies": {
"@storybook/addons": "7.0.0-alpha.10",
"@storybook/api": "7.0.0-alpha.10",
"@storybook/client-logger": "7.0.0-alpha.10",
"@storybook/components": "7.0.0-alpha.10",
"@storybook/core-events": "7.0.0-alpha.10",
"@storybook/addons": "7.0.0-alpha.13",
"@storybook/api": "7.0.0-alpha.13",
"@storybook/client-logger": "7.0.0-alpha.13",
"@storybook/components": "7.0.0-alpha.13",
"@storybook/core-events": "7.0.0-alpha.13",
"@storybook/csf": "0.0.2--canary.4566f4d.1",
"core-js": "^3.8.2",
"global": "^4.4.0",
@ -69,7 +69,7 @@
"publishConfig": {
"access": "public"
},
"gitHead": "b13dd8fb52819d73d4983148af8ffc5d683e8b75",
"gitHead": "9ac4d2e0a05eb945713a0e6689abc3b12359e181",
"storybook": {
"displayName": "Outline",
"unsupportedFrameworks": [

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/addon-storyshots",
"version": "7.0.0-alpha.10",
"version": "7.0.0-alpha.13",
"description": "Take a code snapshot of every story automatically with Jest",
"keywords": [
"addon",
@ -38,12 +38,12 @@
},
"dependencies": {
"@jest/transform": "^26.6.2",
"@storybook/addons": "7.0.0-alpha.10",
"@storybook/addons": "7.0.0-alpha.13",
"@storybook/babel-plugin-require-context-hook": "1.0.1",
"@storybook/client-api": "7.0.0-alpha.10",
"@storybook/core-client": "7.0.0-alpha.10",
"@storybook/core-common": "7.0.0-alpha.10",
"@storybook/core-webpack": "7.0.0-alpha.10",
"@storybook/client-api": "7.0.0-alpha.13",
"@storybook/core-client": "7.0.0-alpha.13",
"@storybook/core-common": "7.0.0-alpha.13",
"@storybook/core-webpack": "7.0.0-alpha.13",
"@storybook/csf": "0.0.2--canary.4566f4d.1",
"@types/glob": "^7.1.3",
"@types/jest": "^26.0.16",
@ -54,7 +54,7 @@
"jest-specific-snapshot": "^4.0.0",
"preact-render-to-string": "^5.1.19",
"pretty-format": "^26.6.2",
"react-test-renderer": "^16.8.0 || ^17.0.0",
"react-test-renderer": "^16.8.0 || ^17.0.0 || ^18.0.0",
"read-pkg-up": "^7.0.1",
"ts-dedent": "^2.0.0"
},
@ -62,16 +62,17 @@
"@angular/core": "^13.3.6",
"@angular/platform-browser-dynamic": "^13.3.6",
"@emotion/jest": "^11.8.0",
"@storybook/addon-docs": "7.0.0-alpha.10",
"@storybook/angular": "7.0.0-alpha.10",
"@storybook/react": "7.0.0-alpha.10",
"@storybook/vue": "7.0.0-alpha.10",
"@storybook/vue3": "7.0.0-alpha.10",
"@storybook/addon-docs": "7.0.0-alpha.13",
"@storybook/angular": "7.0.0-alpha.13",
"@storybook/react": "7.0.0-alpha.13",
"@storybook/vue": "7.0.0-alpha.13",
"@storybook/vue3": "7.0.0-alpha.13",
"babel-loader": "^8.2.5",
"enzyme": "^3.11.0",
"enzyme-to-json": "^3.6.1",
"jest-preset-angular": "^8.3.2",
"jest-vue-preprocessor": "^1.7.1",
"react-test-renderer": "^16",
"rxjs": "^6.6.3",
"vue-jest": "^5.0.0-alpha.8"
},
@ -143,7 +144,7 @@
"publishConfig": {
"access": "public"
},
"gitHead": "b13dd8fb52819d73d4983148af8ffc5d683e8b75",
"gitHead": "9ac4d2e0a05eb945713a0e6689abc3b12359e181",
"storybook": {
"displayName": "Storyshots",
"icon": "https://user-images.githubusercontent.com/263385/101991676-48cdf300-3c7c-11eb-8aa1-944dab6ab29b.png",

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/addon-storyshots-puppeteer",
"version": "7.0.0-alpha.10",
"version": "7.0.0-alpha.13",
"description": "Image snapshots addition to StoryShots based on puppeteer",
"keywords": [
"addon",
@ -35,7 +35,7 @@
"dependencies": {
"@axe-core/puppeteer": "^4.2.0",
"@storybook/csf": "0.0.2--canary.4566f4d.1",
"@storybook/node-logger": "7.0.0-alpha.10",
"@storybook/node-logger": "7.0.0-alpha.13",
"@types/jest-image-snapshot": "^4.1.3",
"core-js": "^3.8.2",
"jest-image-snapshot": "^4.3.0"
@ -46,7 +46,7 @@
"puppeteer": "^2.0.0 || ^3.0.0"
},
"peerDependencies": {
"@storybook/addon-storyshots": "7.0.0-alpha.10",
"@storybook/addon-storyshots": "7.0.0-alpha.13",
"puppeteer": ">=2.0.0"
},
"peerDependenciesMeta": {
@ -57,5 +57,5 @@
"publishConfig": {
"access": "public"
},
"gitHead": "b13dd8fb52819d73d4983148af8ffc5d683e8b75"
"gitHead": "9ac4d2e0a05eb945713a0e6689abc3b12359e181"
}

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/addon-storysource",
"version": "7.0.0-alpha.10",
"version": "7.0.0-alpha.13",
"description": "View a storys source code to see how it works and paste into your app",
"keywords": [
"addon",
@ -35,13 +35,13 @@
"prepare": "node ../../scripts/prepare.js"
},
"dependencies": {
"@storybook/addons": "7.0.0-alpha.10",
"@storybook/api": "7.0.0-alpha.10",
"@storybook/client-logger": "7.0.0-alpha.10",
"@storybook/components": "7.0.0-alpha.10",
"@storybook/router": "7.0.0-alpha.10",
"@storybook/source-loader": "7.0.0-alpha.10",
"@storybook/theming": "7.0.0-alpha.10",
"@storybook/addons": "7.0.0-alpha.13",
"@storybook/api": "7.0.0-alpha.13",
"@storybook/client-logger": "7.0.0-alpha.13",
"@storybook/components": "7.0.0-alpha.13",
"@storybook/router": "7.0.0-alpha.13",
"@storybook/source-loader": "7.0.0-alpha.13",
"@storybook/theming": "7.0.0-alpha.13",
"core-js": "^3.8.2",
"estraverse": "^5.2.0",
"prop-types": "^15.7.2",
@ -67,7 +67,7 @@
"publishConfig": {
"access": "public"
},
"gitHead": "b13dd8fb52819d73d4983148af8ffc5d683e8b75",
"gitHead": "9ac4d2e0a05eb945713a0e6689abc3b12359e181",
"storybook": {
"displayName": "Storysource",
"icon": "https://user-images.githubusercontent.com/263385/101991675-48cdf300-3c7c-11eb-9400-58de5ac6daa7.png",

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/addon-toolbars",
"version": "7.0.0-alpha.10",
"version": "7.0.0-alpha.13",
"description": "Create your own toolbar items that control story rendering",
"keywords": [
"addon",
@ -39,11 +39,11 @@
"prepare": "node ../../scripts/prepare.js"
},
"dependencies": {
"@storybook/addons": "7.0.0-alpha.10",
"@storybook/api": "7.0.0-alpha.10",
"@storybook/client-logger": "7.0.0-alpha.10",
"@storybook/components": "7.0.0-alpha.10",
"@storybook/theming": "7.0.0-alpha.10",
"@storybook/addons": "7.0.0-alpha.13",
"@storybook/api": "7.0.0-alpha.13",
"@storybook/client-logger": "7.0.0-alpha.13",
"@storybook/components": "7.0.0-alpha.13",
"@storybook/theming": "7.0.0-alpha.13",
"core-js": "^3.8.2"
},
"devDependencies": {
@ -64,7 +64,7 @@
"publishConfig": {
"access": "public"
},
"gitHead": "b13dd8fb52819d73d4983148af8ffc5d683e8b75",
"gitHead": "9ac4d2e0a05eb945713a0e6689abc3b12359e181",
"storybook": {
"displayName": "Toolbars",
"icon": "https://user-images.githubusercontent.com/263385/101991677-48cdf300-3c7c-11eb-93b4-19b0e3366959.png",

View File

@ -38,6 +38,14 @@ export const ToolbarMenuList: FC<ToolbarMenuListProps> = withKeyboardCycle(
// Deprecation support for old "name of global arg used as title"
if (showName && !title) {
title = name;
console.warn(
'`showName` is deprecated as `name` will stop having dual purposes in the future. Please specify a `title` in `globalTypes` instead.'
);
} else if (!showName && !icon && !title) {
title = name;
console.warn(
`Using the \`name\` "${name}" as toolbar title for backward compatibility. \`name\` will stop having dual purposes in the future. Please specify either a \`title\` or an \`icon\` in \`globalTypes\` instead.`
);
}
if (dynamicTitle) {

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/addon-viewport",
"version": "7.0.0-alpha.10",
"version": "7.0.0-alpha.13",
"description": "Build responsive components by adjusting Storybooks viewport size and orientation",
"keywords": [
"addon",
@ -36,12 +36,12 @@
"prepare": "node ../../scripts/prepare.js"
},
"dependencies": {
"@storybook/addons": "7.0.0-alpha.10",
"@storybook/api": "7.0.0-alpha.10",
"@storybook/client-logger": "7.0.0-alpha.10",
"@storybook/components": "7.0.0-alpha.10",
"@storybook/core-events": "7.0.0-alpha.10",
"@storybook/theming": "7.0.0-alpha.10",
"@storybook/addons": "7.0.0-alpha.13",
"@storybook/api": "7.0.0-alpha.13",
"@storybook/client-logger": "7.0.0-alpha.13",
"@storybook/components": "7.0.0-alpha.13",
"@storybook/core-events": "7.0.0-alpha.13",
"@storybook/theming": "7.0.0-alpha.13",
"core-js": "^3.8.2",
"global": "^4.4.0",
"memoizerific": "^1.11.3",
@ -65,7 +65,7 @@
"publishConfig": {
"access": "public"
},
"gitHead": "b13dd8fb52819d73d4983148af8ffc5d683e8b75",
"gitHead": "9ac4d2e0a05eb945713a0e6689abc3b12359e181",
"storybook": {
"displayName": "Viewport",
"icon": "https://user-images.githubusercontent.com/263385/101991678-48cdf300-3c7c-11eb-9764-f8af293c1b28.png",

View File

@ -3,35 +3,33 @@ import { skipOn } from '@cypress/skip-test';
describe('addon-docs', () => {
beforeEach(() => {
cy.visitStorybook();
cy.navigateToStory('example-button', 'primary');
cy.viewAddonTab('Docs');
});
it('should have docs tab', () => {
// MDX rendering
cy.getDocsElement().find('h1').should('contain.text', 'Button');
// inline story rendering
cy.getDocsElement().find('button').should('contain.text', 'Button');
cy.navigateToStory('example-button', 'docs');
});
skipOn('vue3', () => {
skipOn('html', () => {
it('should provide source snippet', () => {
cy.getDocsElement()
.find('.docblock-code-toggle')
.first()
.should('contain.text', 'Show code')
// use force click so cypress does not automatically scroll, making the source block visible on this step
.click({ force: true });
skipOn('react', () => {
skipOn('cra', () => {
skipOn('react_legacy_root_api', () => {
it('should provide source snippet', () => {
cy.getDocsElement()
.find('.docblock-code-toggle')
.each(($div) => {
cy.wrap($div)
.should('contain.text', 'Show code')
// use force click so cypress does not automatically scroll, making the source block visible on this step
.click({ force: true });
});
cy.getDocsElement()
.find('pre.prismjs')
.first()
.should(($div) => {
const text = $div.text();
expect(text).not.match(/^\(args\) => /);
cy.getDocsElement()
.find('pre.prismjs')
.each(($div) => {
const text = $div.text();
expect(text).not.match(/^\(args\) => /);
});
});
});
});
});
});
});

View File

@ -5,7 +5,7 @@ describe('Basic CLI', () => {
describe('Welcome story (MDX)', () => {
it('should load and display', () => {
cy.navigateToStory('example-introduction', 'page');
cy.navigateToStory('example-introduction', 'docs');
cy.getDocsElement().should('contain.text', 'Welcome to Storybook');
});
});

View File

@ -41,7 +41,7 @@ Cypress.Commands.add('visitStorybook', () => {
const host = Cypress.env('location') || 'http://localhost:8001';
return cy
.clearLocalStorage()
.visit(`${host}/?path=/story/example-introduction--page`)
.visit(`${host}/?path=/story/example-introduction--docs`)
.get(`#storybook-preview-iframe`, { log: false })
.its('0.contentDocument.body', { log: false })
.should('not.be.empty')
@ -97,9 +97,8 @@ Cypress.Commands.add('navigateToStory', (kind, name) => {
const storyLinkId = `#${kindId}--${storyId}`;
cy.log(`navigateToStory ${kind} ${name}`);
// docs-only stories
if (name !== 'page') {
// Section might be collapsed
// Section might be collapsed
if (Cypress.$(`#${kindId}`).length) {
cy.get(`#${kindId}`).then(async ($item) => {
if ($item.attr('aria-expanded') === 'false') {
await $item.click();
@ -117,7 +116,8 @@ Cypress.Commands.add('navigateToStory', (kind, name) => {
cy.wait(300);
// assert url changes
cy.url().should('include', `path=/story/${kindId}--${storyId}`);
const viewMode = name === 'docs' ? 'docs' : 'story';
cy.url().should('include', `path=/${viewMode}/${kindId}--${storyId}`);
cy.get(storyLinkId).should('have.attr', 'data-selected', 'true');
// A pause is good when switching stories

View File

@ -235,7 +235,6 @@ Let's say you've got a story like this:
'vue/button-story-with-addon-example.js.mdx',
'angular/button-story-with-addon-example.ts.mdx',
'svelte/button-story-with-addon-example.js.mdx',
'svelte/button-story-with-addon-example.native-format.mdx',
]}
/>

View File

@ -200,7 +200,6 @@ When Storybook was initialized, it provided a small set of example stories. Chan
'vue/button-story-with-addon-example.js.mdx',
'angular/button-story-with-addon-example.ts.mdx',
'svelte/button-story-with-addon-example.js.mdx',
'svelte/button-story-with-addon-example.native-format.mdx',
]}
/>

View File

@ -44,7 +44,6 @@ With CSF, every named export in the file represents a story object by default.
'react/my-component-story-basic-and-props.ts.mdx',
'vue/my-component-story-basic-and-props.js.mdx',
'svelte/my-component-story-basic-and-props.js.mdx',
'svelte/my-component-story-basic-and-props.native-format.mdx',
'angular/my-component-story-basic-and-props.ts.mdx',
]}
/>
@ -92,7 +91,6 @@ Consider Storybooks ["Button" example](../writing-stories/introduction.md#def
'vue/button-story-click-handler.2.js.mdx',
'vue/button-story-click-handler.3.js.mdx',
'svelte/button-story-click-handler.js.mdx',
'svelte/button-story-click-handler.native-format.mdx',
'angular/button-story-click-handler.ts.mdx',
]}
/>
@ -125,7 +123,6 @@ Or even more simply:
'react/button-story-click-handler-simplificated.js.mdx',
'angular/button-story-click-handler-simplificated.ts.mdx',
'vue/button-story-click-handler-simplificated.js.mdx',
'svelte/button-story-click-handler-simplificated.native-format.mdx',
]}
/>
@ -158,6 +155,28 @@ A good use case for the `play` function is a form component. With previous Story
When the story renders in the UI, Storybook executes each step defined in the `play` function and runs the assertions without the need for user interaction.
## Custom render functions
Starting in Storybook 6.4, you can write your stories as JavaScript objects, reducing the boilerplate code you need to generate to test your components, thus improving functionality and usability. `Render` functions are helpful methods to give you additional control over how the story renders. For example, if you were writing a story as an object and you wanted to specify how your component should render, you could write the following:
<!-- prettier-ignore-start -->
<CodeSnippets
paths={[
'react/component-story-with-custom-render-function.js.mdx',
'react/component-story-with-custom-render-function.ts.mdx',
'angular/component-story-with-custom-render-function.ts.mdx',
'vue/component-story-with-custom-render-function.js.mdx',
'vue/component-story-with-custom-render-function.ts.mdx',
'preact/component-story-with-custom-render-function.js.mdx',
'web-components/component-story-with-custom-render-function.js.mdx',
]}
/>
<!-- prettier-ignore-end -->
When Storybook loads this story, it will detect the existence of a `render` function and adjust the component rendering accordingly based on what's defined.
## Storybook export vs. name handling
Storybook handles named exports and the `name` option slightly differently. When should you use one vs. the other?

View File

@ -44,7 +44,6 @@ For example, here's the story from the `Checkbox` example above, rewritten in CS
'react/checkbox-story-csf.ts.mdx',
'vue/checkbox-story-csf.js.mdx',
'angular/checkbox-story-csf.ts.mdx',
'svelte/checkbox-story-csf.native-format.mdx',
]}
/>

View File

@ -3,7 +3,7 @@ title: 'Environment variables'
---
You can use environment variables in Storybook to change its behavior in different “modes”.
If you supply an environment variable prefixed with `STORYBOOK_`, it will be available in `process.env`:
If you supply an environment variable prefixed with `STORYBOOK_`, it will be available in `process.env` when using webpack, or `import.meta.env` when using the vite builder:
```shell
STORYBOOK_THEME=red STORYBOOK_DATA_KEY=12345 npm run storybook
@ -60,7 +60,6 @@ Then you can access this environment variable anywhere, even within your stories
'angular/my-component-with-env-variables.mdx.mdx',
'web-components/my-component-with-env-variables.js.mdx',
'svelte/my-component-with-env-variables.js.mdx',
'svelte/my-component-with-env-variables.native-format.mdx',
'svelte/my-component-with-env-variables.mdx.mdx',
]}
/>

View File

@ -24,7 +24,6 @@ Afterward, you can use any asset in your stories:
'angular/component-story-static-asset-with-import.ts.mdx',
'angular/component-story-static-asset-with-import.mdx.mdx',
'svelte/component-story-static-asset-with-import.js.mdx',
'svelte/component-story-static-asset-with-import.native-format.mdx',
'svelte/component-story-static-asset-with-import.mdx.mdx',
]}
/>
@ -61,7 +60,6 @@ Here `../public` is your static directory. Now use it in a component or story li
'angular/component-story-static-asset-without-import.ts.mdx',
'angular/component-story-static-asset-without-import.mdx.mdx',
'svelte/component-story-static-asset-without-import.js.mdx',
'svelte/component-story-static-asset-without-import.native-format.mdx',
'svelte/component-story-static-asset-without-import.mdx.mdx',
]}
/>
@ -112,7 +110,6 @@ Upload your files to an online CDN and reference them. In this example, were
'angular/component-story-static-asset-cdn.ts.mdx',
'angular/component-story-static-asset-cdn.mdx.mdx',
'svelte/component-story-static-asset-cdn.js.mdx',
'svelte/component-story-static-asset-cdn.native-format.mdx',
'svelte/component-story-static-asset-cdn.mdx.mdx',
]}
/>

View File

@ -146,9 +146,7 @@ This feature is experimental, and it has some limitations on what you can and ca
## Configure your project with TypeScript
If you need, you can also configure your Storybook using TypeScript. To get started, add a `.babelrc` file inside your project and include the following Babel presets:
Rename your `.storybook/main.js` to `.storybook/main.ts` and restart your Storybook.
If you would like, you can also write your Storybook configuration using TypeScript. To get started, add a `.babelrc` file inside your project and include the following Babel presets:
<!-- prettier-ignore-start -->
@ -160,9 +158,15 @@ Rename your `.storybook/main.js` to `.storybook/main.ts` and restart your Storyb
<!-- prettier-ignore-end -->
### Using Storybook API
This babel config will be used to process your stories, as well as your config files.
You can also use Storybook's API to configure your project with TypeScript. Under the hood, it mirrors the exact configuration you get by default. Below is an abridged Storybook configuration with TypeScript and additional information about each configuration element.
Alternatively, you can install [`ts-node`](https://typestrong.org/ts-node/) in your project, which will be used to process your config files without the need for a `.babelrc`.
Rename your `.storybook/main.js` to `.storybook/main.ts` and restart your Storybook.
### Using Storybook Types in Your Configuration
You can also use Storybook's TypeScript types to ensure you are using valid options and get autocompletion in your editor. Below is an abridged Storybook configuration with TypeScript types and additional information about each configuration element.
<!-- prettier-ignore-start -->
@ -172,21 +176,24 @@ You can also use Storybook's API to configure your project with TypeScript. Unde
]}
/>
See the vite builder [TypeScript documentation](https://github.com/storybookjs/builder-vite#typescript) if using `@storybook/builder-vite`.
<!-- prettier-ignore-end -->
| Configuration element | Description |
| --------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `stories` | The array of globs that indicates the [location of your story files](#configure-story-loading), relative to `main.ts` |
| `staticDirs` | Sets a list of directories of [static files](./images-and-assets.md#serving-static-files-via-storybook-configuration) to be loaded by Storybook <br/> `staticDirs:['../public']` |
| `addons` | Sets the list of [addons](https://storybook.js.org/addons/) loaded by Storybook <br/> `addons:['@storybook/addon-essentials']` |
| `typescript` | Configures how Storybook handles [TypeScript files](./typescript.md) <br/> `typescript: { check: false, checkOptions: {} }` |
| `framework` | Configures Storybook based on a set of framework-specific settings <br/> `framework:'@storybook/svelte'` |
| `core` | Configures Storybook's internal features.<br/> `core: { builder: 'webpack5' }` |
| `features` | Enables Storybook's additional features.<br/> See table below for a list of available features `features: { storyStoreV7: true }` |
| `refs` | Configures [Storybook composition](../sharing/storybook-composition.md) <br/> `refs:{ example: { title: 'ExampleStorybook', url:'https://your-url.com' } }` |
| `logLevel` | Configures Storybook's logs in the browser terminal. Useful for debugging <br/> `logLevel: 'debug'` |
| `webpackFinal` | Customize Storybook's [Webpack](../builders/webpack.md) setup <br/> `webpackFinal: async (config:any) => { return config; }` |
| `env` | Defines custom Storybook [environment variables](./environment-variables.md#using-storybook-configuration). <br/> `env: (config) => ({...config, EXAMPLE_VAR: 'Example var' }),` |
| Configuration element | Description |
| --------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `stories` | The array of globs that indicates the [location of your story files](#configure-story-loading), relative to `main.ts` |
| `staticDirs` | Sets a list of directories of [static files](./images-and-assets.md#serving-static-files-via-storybook-configuration) to be loaded by Storybook <br/> `staticDirs:['../public']` |
| `addons` | Sets the list of [addons](https://storybook.js.org/addons/) loaded by Storybook <br/> `addons:['@storybook/addon-essentials']` |
| `typescript` | Configures how Storybook handles [TypeScript files](./typescript.md) <br/> `typescript: { check: false, checkOptions: {} }` |
| `framework` | Configures Storybook based on a set of framework-specific settings <br/> `framework:'@storybook/svelte'` |
| `core` | Configures Storybook's internal features.<br/> `core: { builder: 'webpack5' }` |
| `features` | Enables Storybook's additional features.<br/> See table below for a list of available features `features: { storyStoreV7: true }` |
| `refs` | Configures [Storybook composition](../sharing/storybook-composition.md) <br/> `refs:{ example: { title: 'ExampleStorybook', url:'https://your-url.com' } }` |
| `logLevel` | Configures Storybook's logs in the browser terminal. Useful for debugging <br/> `logLevel: 'debug'` |
| `webpackFinal` | Customize Storybook's [Webpack](../builders/webpack.md) setup <br/> `webpackFinal: async (config:any) => { return config; }` |
| `viteFinal` | Customize Storybook's Vite setup when using the [vite builder](https://github.com/storybookjs/builder-vite) <br/> `viteFinal: async (config: Vite.InlineConfig, options: Options) => { return config; }` |
| `env` | Defines custom Storybook [environment variables](./environment-variables.md#using-storybook-configuration). <br/> `env: (config) => ({...config, EXAMPLE_VAR: 'Example var' }),` |
## Configure story rendering

View File

@ -47,7 +47,6 @@ Browse the documentation and look for the code snippets you're willing to contri
'vue/your-component.2.js.mdx',
'vue/your-component.3.js.mdx',
'svelte/your-component.js.mdx',
'svelte/your-component.native-format.mdx',
'web-components/your-component.js.mdx',
]}
/>
@ -70,7 +69,6 @@ Create the file `ember/your-component.js.mdx`, similar to the other frameworks,
'vue/your-component.2.js.mdx',
'vue/your-component.3.js.mdx',
'svelte/your-component.js.mdx',
'svelte/your-component.native-format.mdx',
'web-components/your-component.js.mdx',
'ember/your-component.js.mdx', //👈🏼 The code snippet you created.
]}

View File

@ -119,7 +119,6 @@ Until now, we only used auto-generated controls based on the component we're wri
'vue/table-story-fully-customize-controls.mdx-3.mdx.mdx',
'angular/table-story-fully-customize-controls.ts.mdx',
'angular/table-story-fully-customize-controls.mdx.mdx',
'svelte/table-story-fully-customize-controls.native-format.mdx',
]}
/>
@ -151,7 +150,6 @@ One way to deal with this is to use primitive values (e.g., strings) as arg valu
'angular/component-story-custom-args-complex.ts.mdx',
'angular/component-story-custom-args-complex.mdx.mdx',
'svelte/component-story-custom-args-complex.js.mdx',
'svelte/component-story-custom-args-complex.native-format.mdx',
]}
/>

View File

@ -126,7 +126,6 @@ Update your story through [parameters](../writing-stories/parameters.md) to incl
'angular/my-component-story-configure-viewports.mdx.mdx',
'web-components/my-component-story-configure-viewports.js.mdx',
'svelte/my-component-story-configure-viewports.js.mdx',
'svelte/my-component-story-configure-viewports.native-format.mdx',
'svelte/my-component-story-configure-viewports.mdx.mdx',
]}
/>

View File

@ -20,7 +20,6 @@ Pick a simple component from your project, like a Button, and write a `.stories.
'vue/your-component.3.js.mdx',
'vue/your-component.mdx-3.mdx.mdx',
'svelte/your-component.js.mdx',
'svelte/your-component.native-format.mdx',
'svelte/your-component.mdx.mdx',
'web-components/your-component.js.mdx',
'html/your-component.js.mdx',

View File

@ -22,7 +22,6 @@ Lets start with the `Button` component. A story is a function that describes
'vue/button-story.js.mdx',
'vue/button-story.mdx.mdx',
'svelte/button-story.js.mdx',
'svelte/button-story.native-format.mdx',
'svelte/button-story.mdx.mdx',
'web-components/button-story.js.mdx',
'html/button-story.js.mdx',
@ -54,7 +53,6 @@ The above story definition can be further improved to take advantage of [Storybo
'angular/button-story-with-args.mdx.mdx',
'web-components/button-story-with-args.js.mdx',
'svelte/button-story-with-args.js.mdx',
'svelte/button-story-with-args.native-format.mdx',
'svelte/button-story-with-args.mdx.mdx',
'html/button-story-with-args.js.mdx',
'html/button-story-with-args.ts.mdx',

View File

@ -141,4 +141,50 @@ This level of service can serve published Storybooks but has no further integrat
Examples: [Netlify](https://www.netlify.com/), [S3](https://aws.amazon.com/en/s3/)
</details>
</details>
## Search engine optimization (SEO)
If your Storybook is publically viewable, you may wish to configure how it is represented in search engine result pages.
### Title
Storybook will generate the document title (i.e. `<title>`) for you automatically, to include the currently-viewed component and story. By default, it looks something like "Components / Button - Primary ⋅ Storybook". You can modify the "Storybook" portion by adding the following to the `main.js` file in your config directory:
<!-- prettier-ignore-start -->
<CodeSnippets
paths={[
'common/seo-title.js.mdx',
]}
/>
<!-- prettier-ignore-end -->
### Description
You can provide a description for search engines to display in the results listing, by adding the following to the `manager-head.html` file in your config directory:
<!-- prettier-ignore-start -->
<CodeSnippets
paths={[
'common/seo-description.html.mdx',
]}
/>
<!-- prettier-ignore-end -->
### Preventing your Storybook from being crawled
You can prevent your published Storybook from appearing in search engine results by including a noindex meta tag, which you can do by adding the following to the `manager-head.html` file in your config directory:
<!-- prettier-ignore-start -->
<CodeSnippets
paths={[
'common/seo-noindex.html.mdx',
]}
/>
<!-- prettier-ignore-end -->

View File

@ -1,38 +1,40 @@
```ts
// App.stories.ts
import type { Meta, StoryFn } from '@storybook/angular';
import type { Meta, Story } from '@storybook/angular';
import { AppComponent } from './app.component';
export default {
/* 👇 The title prop is optional.
* See https://storybook.js.org/docs/angular/configure/overview#configure-story-loading
* to learn how to generate automatic titles
*/
* See https://storybook.js.org/docs/7.0/angular/configure/overview#configure-story-loading
* to learn how to generate automatic titles
*/
title: 'App',
component: AppComponent,
} as Meta;
const Template: StoryFn = () => ({
props: {},
});
export const Success = Template.bind({});
Success.parameters = {
fetch: {
json: {
JavaScript: 3390991,
'C++': 44974,
TypeScript: 15530,
CoffeeScript: 12253,
Python: 9383,
C: 5341,
Shell: 5115,
HTML: 3420,
CSS: 3171,
Makefile: 189,
/*
*👇 Render functions are a framework specific feature to allow you control on how the component renders.
* See https://storybook.js.org/docs/7.0/angular/api/csf
* to learn how to use render functions.
*/
export const Success: Story = {
parameters: {
fetch: {
json: {
JavaScript: 3390991,
'C++': 44974,
TypeScript: 15530,
CoffeeScript: 12253,
Python: 9383,
C: 5341,
Shell: 5115,
HTML: 3420,
CSS: 3171,
Makefile: 189,
},
},
},
};
```
```

View File

@ -12,24 +12,30 @@ import { Icon } from './icon.component';
<Meta title="MDX/Badge" component={Badge} />
<!--
👇 Render functions are a framework specific feature to allow you control on how the component renders.
See https://storybook.js.org/docs/7.0/angular/api/csf
to learn how to use render functions.
-->
# Badge
Let's define a story for our `Badge` component:
<Story name="positive">
{{
<Story
name="positive"
render={() => ({
template:`<Badge status="positive">Positive</Badge>`,
}}
</Story>
})} />
We can drop it in a `Canvas` to get a code snippet:
<Canvas>
<Story name="negative">
{{
<Story
name="negative"
render={() => ({
template: `<Badge status="negative">Negative</Badge>`,
}}
</Story>
})} />
</Canvas>
We can even preview multiple stories in a block. This
@ -37,37 +43,36 @@ gets rendered as a group, but defines individual stories
with unique URLs and isolated snapshot tests.
<Canvas>
<Story name="warning">
{{
template: `<Badge status="warning">Warning</Badge>`,
}}
</Story>
<Story name="neutral">
{{
template: `<Badge status="neutral">Neutral</Badge>`,
}}
</Story>
<Story name="error">
{{
template: `<Badge status="error">Error</Badge>`,
}}
</Story>
<Story
name="warning"
render={() => ({
template: `<Badge status="warning">Warning</Badge>`,
})} />
<Story
name="neutral"
render={() => ({
template: `<Badge status="neutral">Neutral</Badge>`,
})} />
<Story
name="error"
render={() => ({
template: `<Badge status="error">Error</Badge>`,
})} />
<Story
name="with icon"
decorators={[
moduleMetadata({
declarations: [Badge, Icon],
imports: [CommonModule],
declarations: [Badge, Icon],
imports: [CommonModule],
})
]}>
{{
]}
render={() => ({
template: `
<Badge status="warning">
<Icon icon="check" inline></Icon>
with icon
</Badge>
`,
}}
</Story>
})} />
</Canvas>
```
```

View File

@ -7,7 +7,11 @@ import { Badge } from './badge.component';
<Meta title="MDX/Badge" component={Badge} />
export const Template = (args) => ({ props: args });
<!--
👇 Render functions are a framework specific feature to allow you control on how the component renders.
See https://storybook.js.org/docs/7.0/angular/api/csf
to learn how to use render functions.
-->
# Badge
@ -17,10 +21,11 @@ Let's define a story for our `Badge` component:
name="positive"
args={{
status: 'positive',
label: 'Positive'
}}>
{Template.bind({})}
</Story>
label: 'Positive',
}}
render={(args) => ({
props: args,
})} />
We can drop it in a `Canvas` to get a code snippet:
@ -28,11 +33,12 @@ We can drop it in a `Canvas` to get a code snippet:
<Story
name="negative"
args={{
status: 'negative',
label: 'Negative'
}}>
{Template.bind({})}
</Story>
status: 'negative',
label: 'Negative',
}}
render={(args) => ({
props: args,
})} />
</Canvas>
We can even preview multiple Stories in a block. This
@ -41,36 +47,31 @@ with unique URLs, which is great for review and testing.
<Canvas>
<Story
name="warning"
name="warning"
args={{
status: 'warning',
label: 'Warning'
}}>
{Template.bind({})}
</Story>
label: 'Warning',
}}
render={(args) => ({
props: args,
})} />
<Story
name="neutral"
name="neutral"
args={{
status: 'neutral',
label: 'Neutral'
}}>
{Template.bind({})}
</Story>
label: 'Neutral',
}}
render={(args) => ({
props: args,
})} />
<Story
name="error"
args={{
status: 'error',
label: 'Error'
}}>
{Template.bind({})}
</Story>
<Story
name="with icon"
args={{
status: 'warning',
label: (<Icon icon="check" inline /> with icon)
)}}>
{Template.bind({})}
</Story>
label: 'Error',
}}
render={(args) => ({
props: args,
})} />
</Canvas>
```
```

View File

@ -1,6 +1,6 @@
```shell
# Builds Storybook with Angular's custom builder
# See https://storybook.js.org/docs/angular/get-started/install
# See https://storybook.js.org/docs/7.0/angular/get-started/install
# to learn how to create the custom builder
ng run my-project:build-storybook
```

View File

@ -13,9 +13,9 @@ import * as ButtonStories from './Button.stories';
export default {
/* 👇 The title prop is optional.
* See https://storybook.js.org/docs/angular/configure/overview#configure-story-loading
* See https://storybook.js.org/docs/7.0/angular/configure/overview#configure-story-loading
* to learn how to generate automatic titles
*/
*/
title: 'ButtonGroup',
component: ButtonGroup,
decorators: [
@ -26,16 +26,15 @@ export default {
],
} as Meta;
const Template: StoryFn = (args) => ({
props: args,
});
export const Pair = Template.bind({});
Pair.args = {
buttons: [
{ ...ButtonStories.Primary.args },
{ ...ButtonStories.Secondary.args },
],
orientation: 'horizontal',
/*
*👇 Render functions are a framework specific feature to allow you control on how the component renders.
* See https://storybook.js.org/docs/7.0/angular/api/csf
* to learn how to use render functions.
*/
export const Pair: Story = {
args: {
buttons: [{ ...ButtonStories.Primary.args }, { ...ButtonStories.Secondary.args }],
orientation: 'horizontal',
},
};
```
```

View File

@ -1,7 +1,7 @@
```ts
// Button.stories.ts
import type { Meta, StoryFn } from '@storybook/angular';
import type { Meta, Story } from '@storybook/angular';
import { action } from '@storybook/addon-actions';
@ -9,22 +9,21 @@ import { Button } from './button.component';
export default {
/* 👇 The title prop is optional.
* See https://storybook.js.org/docs/angular/configure/overview#configure-story-loading
* to learn how to generate automatic titles
*/
* See https://storybook.js.org/docs/7.0/angular/configure/overview#configure-story-loading
* to learn how to generate automatic titles
*/
title: 'Button',
component: Button,
} as Meta;
export const Text: StoryFn = ({ label, onClick }) => ({
props: {
label,
onClick,
export const Text: Story = {
render: (args) => ({
props: args,
template: `<storybook-button [label]="label" (onClick)="onClick()"></storybook-button>`,
}),
args: {
label: 'Hello',
onClick: action('clicked'),
},
});
Text.args = {
label: 'Hello',
onClick: action('clicked'),
};
```
```

View File

@ -1,20 +1,20 @@
```ts
// Button.stories.ts
import type { Meta, StoryFn } from '@storybook/angular';
import type { Meta, Story } from '@storybook/angular';
import { Button } from './button.component';
export default {
/* 👇 The title prop is optional.
* See https://storybook.js.org/docs/angular/configure/overview#configure-story-loading
* to learn how to generate automatic titles
*/
* See https://storybook.js.org/docs/7.0/angular/configure/overview#configure-story-loading
* to learn how to generate automatic titles
*/
title: 'Button',
component: Button,
} as Meta;
export const Text: StoryFn = (args) => ({
props: args,
});
```
export const Text: Story = {
args: {...},
};
```

View File

@ -1,7 +1,7 @@
```ts
// Button.stories.ts
import type { Meta, StoryFn } from '@storybook/angular';
import type { Meta, Story } from '@storybook/angular';
import { Button } from './button.component';
@ -9,17 +9,19 @@ import { action } from '@storybook/addon-actions';
export default {
/* 👇 The title prop is optional.
* See https://storybook.js.org/docs/angular/configure/overview#configure-story-loading
* to learn how to generate automatic titles
*/
title: 'Button',
* See https://storybook.js.org/docs/7.0/angular/configure/overview#configure-story-loading
* to learn how to generate automatic titles
*/
title: 'Button',
component: Button,
} as Meta;
export const Text: StoryFn = () => ({
props: {
text: 'Hello Button',
onClick: action('clicked'),
},
});
```
export const Text: Story = {
render: () => ({
props: {
label: 'Button',
onClick: action('clicked'),
},
}),
};
```

View File

@ -7,9 +7,9 @@ import { Button } from './button.component';
export default {
/* 👇 The title prop is optional.
* See https://storybook.js.org/docs/angular/configure/overview#configure-story-loading
* to learn how to generate automatic titles
*/
* See https://storybook.js.org/docs/7.0/angular/configure/overview#configure-story-loading
* to learn how to generate automatic titles
*/
title: 'Button',
component: Button,
//👇 Creates specific argTypes

View File

@ -9,9 +9,9 @@ import { Parent } from './parent.component'; // Parent contains ng-content
export default {
/* 👇 The title prop is optional.
* See https://storybook.js.org/docs/angular/configure/overview#configure-story-loading
* to learn how to generate automatic titles
*/
* See https://storybook.js.org/docs/7.0/angular/configure/overview#configure-story-loading
* to learn how to generate automatic titles
*/
title: 'Button',
component: Button,
decorators: [

View File

@ -13,18 +13,15 @@ import { Parent } from './parent.component';
<Meta title="Button" component={Button}/>
export const Template = () => ({
template: `<app-button label="Submit"></app-button>`,
});
<!-- With a template -->
<Story
name="Primary"
decorators={[
componentWrapperDecorator((story) => `<div style="margin: 3em">${story}</div>`)
]} >
{Template.bind({})}
]}
render={() => ({
template: `<app-button label="Submit"></app-button>`,
})} />
</Story>
<!-- With a component -->
@ -36,7 +33,9 @@ export const Template = () => ({
declarations: [ParentComponent],
}),
componentWrapperDecorator(ParentComponent)
]} >
{Template.bind({})}
]}
render={() => ({
template: `<app-button label="Submit"></app-button>`,
})} />
</Story>
```

View File

@ -8,31 +8,23 @@ import { Parent } from './parent.component'; // Parent contains ng-content
export default {
/* 👇 The title prop is optional.
* See https://storybook.js.org/docs/angular/configure/overview#configure-story-loading
* to learn how to generate automatic titles
*/
* See https://storybook.js.org/docs/7.0/angular/configure/overview#configure-story-loading
* to learn how to generate automatic titles
*/
title: 'Button',
component: Button,
} as Meta;
const Template: Story = (args) => ({
template: '<app-button label="Submit"></app-button>',
});
export const Primary = Template.bind({});
Primary.decorators = [
componentWrapperDecorator((story) => `<div style="margin: 3em">${story}</div>`),
];
export const Primary = {
export const Primary: Story = {
decorators: [componentWrapperDecorator((story) => `<div style="margin: 3em">${story}</div>`)],
};
export const InsideParent= Template.bind({});
InsideParent.decorators = [
moduleMetadata({
declarations: [Parent],
}),
componentWrapperDecorator(Parent),
];
export const InsideParent: Story = {
decorators: [
moduleMetadata({
declarations: [Parent],
}),
componentWrapperDecorator(Parent),
],
};
```

View File

@ -1,43 +0,0 @@
```md
<!-- Button.stories.mdx -->
import { Meta, Story } from '@storybook/addon-docs';
import { Button } from './button.component';
<!-- 👇 Creates specific argTypes -->
<Meta
title="Button"
component={Button}
argTypes={{
backgroundColor: {
control: 'color',
},
}}
/>
<!-- 👇 Some function to demonstrate the behavior -->
export const someFunction = (someValue) => {
return `i am a ${someValue}`;
};
<!-- 👇 Destructure the label from the args object and assigns the function result to a variable and pass it as a prop into the component -->
<Story
name="ExampleStory"
args={{
primary: true,
size: 'small',
label: 'button',
}}>
{(args) => {
const { label } = args;
const functionResult = someFunction(label);
return {
props: {
...args,
label: functionResult,
},
};
}}
</Story>
```

View File

@ -1,45 +0,0 @@
```ts
// Button.stories.ts
import type { Meta, StoryFn } from '@storybook/angular';
import { Button } from './button.component';
export default {
/* 👇 The title prop is optional.
* See https://storybook.js.org/docs/angular/configure/overview#configure-story-loading
* to learn how to generate automatic titles
*/
title: 'Button',
component: Button,
//👇 Creates specific argTypes
argTypes: {
backgroundColor: { control: 'color' },
},
} as Meta;
//👇 Some function to demonstrate the behavior
const someFunction = (someValue: string) => {
return `i am a ${someValue}`;
};
export const ExampleStory: StoryFn = (args) => {
//👇 Destructure the label from the args object
const { label } = args;
//👇 Assigns the function result to a variable and pass it as a prop into the component
const functionResult = someFunction(label);
return {
props: {
...args,
label: functionResult,
},
};
};
ExampleStory.args = {
primary: true,
size: 'small',
label: 'button',
};
```

View File

@ -7,9 +7,9 @@ import { Button } from './button.component';
export default {
/* 👇 The title prop is optional.
* See https://storybook.js.org/docs/angular/configure/overview#configure-story-loading
* to learn how to generate automatic titles
*/
* See https://storybook.js.org/docs/7.0/angular/configure/overview#configure-story-loading
* to learn how to generate automatic titles
*/
title: 'Button',
component: Button,
} as Meta;

View File

@ -1,26 +1,31 @@
```ts
// Button.stories.ts
import type { Meta, StoryFn } from '@storybook/angular';
import type { Meta, Story } from '@storybook/angular';
import { Button } from './button.component';
export default {
/* 👇 The title prop is optional.
* See https://storybook.js.org/docs/angular/configure/overview#configure-story-loading
* to learn how to generate automatic titles
*/
* See https://storybook.js.org/docs/7.0/angular/configure/overview#configure-story-loading
* to learn how to generate automatic titles
*/
title: 'Button',
component: Button,
} as Meta;
export const Primary: StoryFn = () => ({
props: {
label: 'Button',
primary: true,
},
});
Primary.storyName = 'I am the primary';
```
/*
*👇 Render functions are a framework specific feature to allow you control on how the component renders.
* See https://storybook.js.org/docs/7.0/angular/api/csf
* to learn how to use render functions.
*/
export const Primary: Story = {
name: 'I am the primary',
render: () => ({
props: {
label: 'Button',
primary: true,
},
}),
};
```

View File

@ -1,45 +1,42 @@
```ts
// Button.stories.ts
import type { Meta, StoryFn } from '@storybook/angular';
import type { Meta, Story } from '@storybook/angular';
import { Button } from './button.component';
export default {
/* 👇 The title prop is optional.
* See https://storybook.js.org/docs/angular/configure/overview#configure-story-loading
* to learn how to generate automatic titles
*/
* See https://storybook.js.org/docs/7.0/angular/configure/overview#configure-story-loading
* to learn how to generate automatic titles
*/
title: 'Button',
component: Button,
} as Meta;
//👇 We create a “template” of how args map to rendering
const Template: StoryFn = (args) => ({
props: args,
});
// 👇 Each story then reuses that template
export const Primary= Template.bind({});
Primary.args = {
label: 'Button',
backgroundColor: '#ff0',
/*
*👇 Render functions are a framework specific feature to allow you control on how the component renders.
* See https://storybook.js.org/docs/7.0/angular/api/csf
* to learn how to use render functions.
*/
export const Primary: Story = {
args: {
label: 'Button',
backgroundColor: '#ff0',
},
};
export const Secondary= Template.bind({});
Secondary.args = {
export const Secondary: Story = {
args: {
...Primary.args,
label: '😄👍😍💯',
},
};
export const Tertiary= Template.bind({});
Tertiary.args={
...Primary.args,
label: '📚📕📈🤓',
export const Tertiary: Story = {
args: {
...Primary.args,
label: '📚📕📈🤓',
},
};
```
```

View File

@ -1,15 +1,15 @@
```ts
// Button.stories.ts
import type { Meta, StoryFn } from '@storybook/angular';
import type { Meta, Story } from '@storybook/angular';
import { Button } from './button.component';
export default {
/* 👇 The title prop is optional.
* See https://storybook.js.org/docs/angular/configure/overview#configure-story-loading
* to learn how to generate automatic titles
*/
* See https://storybook.js.org/docs/7.0/angular/configure/overview#configure-story-loading
* to learn how to generate automatic titles
*/
title: 'Button',
component: Button,
//👇 Creates specific parameters for the story
@ -20,7 +20,14 @@ export default {
},
} as Meta;
export const Basic: StoryFn = () => ({
template: `<app-button>hello</<app-button>`,
});
```
/*
*👇 Render functions are a framework specific feature to allow you control on how the component renders.
* See https://storybook.js.org/docs/7.0/angular/api/csf
* to learn how to use render functions.
*/
export const Basic: Story = {
render: () => ({
template: `<app-button>hello</<app-button>`,
}),
};
```

View File

@ -7,16 +7,19 @@ import { Button } from './button.component';
<Meta title="Button" component={Button} />
<!-- 👇 We create a “template” of how args map to rendering -->
export const Template = (args) => ({ props: args });
<!--
👇 Render functions are a framework specific feature to allow you control on how the component renders.
See https://storybook.js.org/docs/7.0/angular/api/csf
to learn how to use render functions.
-->
<!-- 👇 Each story then reuses that template -->
<Story
name="Primary"
args={{
primary: true,
label: 'Button',
}} >
{Template.bind({})}
</Story>
}}
render={(args) => ({
props: args,
})} />
```

View File

@ -1,29 +1,28 @@
```ts
// Button.stories.ts
import type { Meta, StoryFn } from '@storybook/angular/';
import type { Meta, Story } from '@storybook/angular/';
import { Button } from './button.component';
export default {
/* 👇 The title prop is optional.
* See https://storybook.js.org/docs/angular/configure/overview#configure-story-loading
* to learn how to generate automatic titles
*/
* See https://storybook.js.org/docs/7.0/angular/configure/overview#configure-story-loading
* to learn how to generate automatic titles
*/
title: 'Button',
component: Button,
} as Meta;
//👇 We create a “template” of how args map to rendering
const Template: StoryFn = (args) => ({
props: args,
});
//👇 Each story then reuses that template
export const Primary = Template.bind({});
Primary.args = {
primary: true,
label: 'Button',
/*
*👇 Render functions are a framework specific feature to allow you control on how the component renders.
* See https://storybook.js.org/docs/7.0/angular/api/csf
* to learn how to use render functions.
*/
export const Primary: Story = {
args: {
primary: true,
label: 'Button',
},
};
```
```

View File

@ -7,9 +7,9 @@ import { Button } from './button.component';
export default {
/* 👇 The title prop is optional.
* See https://storybook.js.org/docs/angular/configure/overview#configure-story-loading
* to learn how to generate automatic titles
*/
* See https://storybook.js.org/docs/7.0/angular/configure/overview#configure-story-loading
* to learn how to generate automatic titles
*/
title: 'Button',
component: Button,
//👇 Creates specific parameters for the story

View File

@ -7,30 +7,34 @@ import { Button } from './button.component';
<Meta title="Button" component={Button}/>
<Story name="Primary">
{{
<!--
👇 Render functions are a framework specific feature to allow you control on how the component renders.
See https://storybook.js.org/docs/7.0/angular/api/csf
to learn how to use render functions.
-->
<Story
name="Primary"
render={() => ({
props: {
background: '#ff0',
backgroundColor: '#ff0',
label: 'Button',
},
}}
</Story>
<Story name="Secondary">
{{
})} />
<Story
name="Secondary"
render={() => ({
props: {
background: '#ff0',
backgroundColor: '#ff0',
label: '😄👍😍💯',
},
}}
</Story>
<Story name="Tertiary">
{{
})} />
<Story
name="Tertiary"
render={() => ({
props: {
background: '#ff0',
backgroundColor: '#ff0',
label: '📚📕📈🤓',
},
}}
</Story>
})} />
```

View File

@ -1,38 +1,48 @@
```ts
// Button.stories.ts
import type { Meta, StoryFn } from '@storybook/angular';
import type { Meta, Story } from '@storybook/angular';
import { Button } from './button.component';
export default {
/* 👇 The title prop is optional.
* See https://storybook.js.org/docs/angular/configure/overview#configure-story-loading
* to learn how to generate automatic titles
*/
* See https://storybook.js.org/docs/7.0/angular/configure/overview#configure-story-loading
* to learn how to generate automatic titles
*/
title: 'Button',
component: Button,
};
export const Primary: StoryFn = () => ({
props: {
label: 'Button',
backgroundColor: '#ff0',
},
});
/*
*👇 Render functions are a framework specific feature to allow you control on how the component renders.
* See https://storybook.js.org/docs/7.0/angular/api/csf
* to learn how to use render functions.
*/
export const Primary: Story = {
render: () => ({
props: {
label: 'Button',
backgroundColor: '#ff0',
},
}),
};
export const Secondary: Story = {
render: () => ({
props: {
label: '😄👍😍💯',
backgroundColor: '#ff0',
},
}),
};
export const Secondary: StoryFn = () => ({
props: {
label: '😄👍😍💯',
backgroundColor: '#ff0',
},
});
export const Tertiary: StoryFn = () => ({
props: {
label: '📚📕📈🤓',
backgroundColor: '#ff0',
},
});
```
export const Tertiary: Story = {
render: () => ({
props: {
label: '📚📕📈🤓',
backgroundColor: '#ff0',
},
}),
};
```

View File

@ -1,15 +1,15 @@
```ts
// Button.stories.ts
import { Meta } from '@storybook/angular';
import type { Meta } from '@storybook/angular';
import { Button } from './button.component';
export default {
/* 👇 The title prop is optional.
* See https://storybook.js.org/docs/angular/configure/overview#configure-story-loading
* to learn how to generate automatic titles
*/
* See https://storybook.js.org/docs/7.0/angular/configure/overview#configure-story-loading
* to learn how to generate automatic titles
*/
title: 'Button',
component: Button,
parameters: {

View File

@ -9,12 +9,12 @@ import { Button } from './button.component.ts';
# Button
<Story name="Primary">
{{
<Story
name="Primary"
render={() => ({
props: {
primary: true,
label: 'Button',
},
}}
</Story>
})} />
```

View File

@ -1,23 +1,30 @@
```ts
// Button.stories.ts
import type { Meta, StoryFn } from '@storybook/angular';
import type { Meta, Story } from '@storybook/angular';
import { Button } from './button.component';
export default {
/* 👇 The title prop is optional.
* See https://storybook.js.org/docs/angular/configure/overview#configure-story-loading
* to learn how to generate automatic titles
*/
* See https://storybook.js.org/docs/7.0/angular/configure/overview#configure-story-loading
* to learn how to generate automatic titles
*/
title: 'Button',
component: Button,
} as Meta;
export const Primary: StoryFn = () => ({
props: {
label: 'Button',
primary: true,
},
});
```
/*
*👇 Render functions are a framework specific feature to allow you control on how the component renders.
* See https://storybook.js.org/docs/7.0/angular/api/csf
* to learn how to use render functions.
*/
export const Primary: Story = {
render: () => ({
props: {
label: 'Button',
primary: true,
},
}),
};
```

View File

@ -1,26 +1,33 @@
```ts
// Checkbox.stories.ts
import type { Meta, StoryFn } from '@storybook/angular';
import type { Meta, Story } from '@storybook/angular';
import { Checkbox } from './Checkbox.component';
export default {
/* 👇 The title prop is optional.
* See https://storybook.js.org/docs/angular/configure/overview#configure-story-loading
* to learn how to generate automatic titles
*/
title: 'Checkbox',
* See https://storybook.js.org/docs/7.0/angular/configure/overview#configure-story-loading
* to learn how to generate automatic titles
*/
title: 'Checkbox',
component: Checkbox,
} as Meta;
export const allCheckboxes: StoryFn = () => ({
template: `
<form>
<Checkbox id="Unchecked" label="Unchecked" />
<Checkbox id="Checked" label="Checked" checked />
<Checkbox appearance="secondary" id="second" label="Secondary" checked />
</form>
`,
});
```
/*
*👇 Render functions are a framework specific feature to allow you control on how the component renders.
* See https://storybook.js.org/docs/7.0/angular/api/csf
* to learn how to use render functions.
*/
export const allCheckboxes: Story = {
render: () => ({
template: `
<form>
<Checkbox id="Unchecked" label="Unchecked" />
<Checkbox id="Checked" label="Checked" checked />
<Checkbox appearance="secondary" id="second" label="Secondary" checked />
</form>
`,
}),
};
```

View File

@ -7,18 +7,23 @@ import { Checkbox } from './checkbox.component';
<Meta title="MDX/Checkbox" component={Checkbox} />
<!--
👇 Render functions are a framework specific feature to allow you control on how the component renders.
See https://storybook.js.org/docs/7.0/angular/api/csf
to learn how to use render functions.
-->
<Canvas>
<Story
name="all checkboxes">
{{
name="MyStory"
render={() => ({
template: `
<form>
<Checkbox id="Unchecked" label="Unchecked" />
<Checkbox id="Checked" label="Checked" checked />
<Checkbox appearance="secondary" id="second" label="Secondary" checked />
</form>
`,
}}
<Checkbox id="Unchecked" label="Unchecked" />
<Checkbox id="Checked" label="Checked" checked />
<Checkbox appearance="secondary" id="second" label="Secondary" checked />
</form>`,
})} >
</Story>
</Canvas>
```

View File

@ -7,7 +7,11 @@ import { Checkbox } from './checkbox.component';
<Meta title="MDX/Checkbox" component={Checkbox} />
export const Template = (args) => ({ props: args });
<!--
👇 Render functions are a framework specific feature to allow you control on how the component renders.
See https://storybook.js.org/docs/7.0/angular/api/csf
to learn how to use render functions.
-->
# Checkbox
@ -19,27 +23,28 @@ Markdown documentation.
name="Unchecked"
args={{
label: 'Unchecked',
}}>
{Template.bind({})}
</Story>
}}
render={(args) => ({
props: args,
})} />
<Story
name="Checked"
args={{
label: 'Unchecked',
checked: true,
}}>
{Template.bind({})}
</Story>
}}
render={(args) => ({
props: args,
})} />
<Story
name="Secondary"
args={{
label: 'Secondary',
checked: true,
appearance: 'secondary',
}}>
{Template.bind({})}
</Story>
}}
render={(args) => ({
props: args,
})} />
</Canvas>
```

View File

@ -15,22 +15,9 @@ export const someFunction = (valuePropertyA, valuePropertyB) => {
};
export const Template = (args) => {
const { propertyA, propertyB } = args;
// 👇 Assigns the function result to a variable
const someFunctionResult = someFunction(propertyA, propertyB);
return {
props: {
...args,
someProperty: someFunctionResult,
},
};
};
<Canvas>
<Story
name="ExampleStory"
name="A complex case with a function"
argTypes={{
propertyA: {
options: [
@ -50,8 +37,16 @@ export const Template = (args) => {
args={{
propertyA: 'Item One',
propertyB: 'Another Item One',
}}>
{Template.bind({})}
</Story>
</Canvas
}}
render={(args) => {
const { propertyA, propertyB } = args;
const someFunctionResult = someFunction(propertyA, propertyB);
return {
props: {
...args,
someProperty: someFunctionResult,
},
};
}} />
</Canvas>
```

View File

@ -1,15 +1,15 @@
```ts
// YourComponent.stories.ts
import { Meta, Story} from '@storybook/angular';
import type { Meta, Story } from '@storybook/angular';
import { YourComponent } from './your-component.component';
export default {
/* 👇 The title prop is optional.
* See https://storybook.js.org/docs/angular/configure/overview#configure-story-loading
* to learn how to generate automatic titles
*/
* See https://storybook.js.org/docs/7.0/angular/configure/overview#configure-story-loading
* to learn how to generate automatic titles
*/
title: 'YourComponent',
component: YourComponent,
//👇 Creates specific argTypes with options
@ -29,23 +29,23 @@ const someFunction = (valuePropertyA: String, valuePropertyB: String) => {
// Makes some computations and returns something
};
const Template: Story = (args) => {
const { propertyA, propertyB } = args;
//👇 Assigns the function result to a variable
const someFunctionResult = someFunction(propertyA, propertyB);
return {
props: {
...args,
someProperty: someFunctionResult,
},
};
};
export const ExampleStory = Template.bind({});
ExampleStory.args= {
propertyA: 'Item One',
propertyB: 'Another Item One',
/*
*👇 Render functions are a framework specific feature to allow you control on how the component renders.
* See https://storybook.js.org/docs/7.0/angular/api/csf
* to learn how to use render functions.
*/
export const ExampleStory: Story = {
render: (args) => {
const { propertyA, propertyB } = args;
//👇 Assigns the function result to a variable
const someFunctionResult = someFunction(propertyA, propertyB);
return {
props: {
...args,
someProperty: someFunctionResult,
},
};
},
args: { propertyA: 'Item One', propertyB: 'Another Item One' },
};
```

View File

@ -9,7 +9,11 @@ import { MyComponent } from './MyComponent.component';
<Meta title="FigmaExample" component={MyComponent} decorators={[withDesign]} />
export const Template = () => ({ props: {} });
<!--
👇 Render functions are a framework specific feature to allow you control on how the component renders.
See https://storybook.js.org/docs/7.0/angular/api/csf
to learn how to use render functions.
-->
<Canvas>
<Story
@ -20,8 +24,8 @@ export const Template = () => ({ props: {} });
url: 'https://www.figma.com/file/Sample-File',
},
}}
>
{Template.bind({})}
</Story>
render={(args) => ({
props: args,
})} />
</Canvas>
```

View File

@ -1,29 +1,25 @@
```ts
// MyComponent.stories.ts
import type { Meta, StoryFn } from '@storybook/angular';
import type { Story, Meta } from '@storybook/angular/';
import { withDesign } from 'storybook-addon-designs';
import { MyComponent } from './MyComponent.component';
// More on default export: https://storybook.js.org/docs/angular/writing-stories/introduction#default-export
// More on default export: https://storybook.js.org/docs/7.0/angular/writing-stories/introduction#default-export
export default {
title: 'FigmaExample',
component: MyComponent,
decorators: [withDesign],
} as Meta;
// More on component templates: https://storybook.js.org/docs/angular/writing-stories/introduction#using-args
const Template: StoryFn = () => ({
props: {},
});
export const Example = Template.bind({});
Example.parameters = {
design: {
type: 'figma',
url: 'https://www.figma.com/file/Sample-File',
export const Example: Story = {
parameters: {
design: {
type: 'figma',
url: 'https://www.figma.com/file/Sample-File',
},
},
};
```
```

View File

@ -7,9 +7,18 @@ import { Button } from './button.component';
<Meta title="Button" component={Button} />
export const Template = (args) => ({ props: args });
<!--
👇 Render functions are a framework specific feature to allow you control on how the component renders.
See https://storybook.js.org/docs/7.0/angular/api/csf
to learn how to use render functions.
-->
<Story name="Basic" args={{ label: 'hello' }}>
{Template.bind({})}
</Story>
<Story
name="Basic"
args={{
label: 'hello'
}}
render={(args) => ({
props: args,
})} />
```

View File

@ -8,13 +8,15 @@ import { MyComponent } from './MyComponent.component';
<Meta title="img" component={MyComponent}/>
<!--
👇 Render functions are a framework specific feature to allow you control on how the component renders.
See https://storybook.js.org/docs/7.0/angular/api/csf
to learn how to use render functions.
-->
<Story
name="WithAnImage">
{{
props: {
src: 'https://place-hold.it/350x150',
alt: 'My CDN placeholder',
},
}}
</Story>
name="WithAnImage"
render={() => ({
template: `<img src="https://place-hold.it/350x150" alt="My CDN placeholder" />`,
})} />
```

View File

@ -1,24 +1,30 @@
```ts
// MyComponent.stories.ts
import type { Meta, StoryFn } from '@storybook/angular';
import type { Meta, Story } from '@storybook/angular';
import { MyComponent } from './MyComponent.component';
export default {
/* 👇 The title prop is optional.
* See https://storybook.js.org/docs/angular/configure/overview#configure-story-loading
* to learn how to generate automatic titles
*/
* See https://storybook.js.org/docs/7.0/angular/configure/overview#configure-story-loading
* to learn how to generate automatic titles
*/
title: 'img',
component: MyComponent,
} as Meta;
export const WithAnImage: StoryFn = () => ({
props: {
src: 'https://place-hold.it/350x150',
alt: 'My CDN placeholder',
},
});
```
/*
*👇 Render functions are a framework specific feature to allow you control on how the component renders.
* See https://storybook.js.org/docs/7.0/angular/api/csf
* to learn how to use render functions.
*/
export const WithAnImage: Story = {
render: () => ({
props: {
src: 'https://place-hold.it/350x150',
alt: 'My CDN placeholder',
},
}),
};
```

View File

@ -9,18 +9,24 @@ import imageFile from './static/image.png';
<Meta title="img" component={MyComponent}/>
<!--
👇 Render functions are a framework specific feature to allow you control on how the component renders.
See https://storybook.js.org/docs/7.0/angular/api/csf
to learn how to use render functions.
-->
export const image = {
src: imageFile,
alt: 'my image',
};
<Story name="WithAnImage">
{{
<Story
name="WithAnImage"
render={() => ({
props: {
src: image.src,
alt: image.alt,
},
template: `<img src="{{src}}" alt="{{alt}}" />`,
}}
</Story>
})} />
```

View File

@ -1,7 +1,7 @@
```ts
// MyComponent.stories.ts
import type { Meta, StoryFn } from '@storybook/angular';
import type { Meta, Story } from '@storybook/angular';
import { MyComponent } from './MyComponent.component';
@ -9,9 +9,9 @@ import imageFile from './static/image.png';
export default {
/* 👇 The title prop is optional.
* See https://storybook.js.org/docs/angular/configure/overview#configure-story-loading
* to learn how to generate automatic titles
*/
* See https://storybook.js.org/docs/7.0/angular/configure/overview#configure-story-loading
* to learn how to generate automatic titles
*/
title: 'img',
component: MyComponent,
} as Meta;
@ -21,11 +21,18 @@ const image = {
alt: 'my image',
};
export const WithAnImage: StoryFn () => ({
template: `<img src="{{src}}" alt="{{alt}}" />`,
props: {
src: image.src,
alt: image.alt,
},
});
```
/*
*👇 Render functions are a framework specific feature to allow you control on how the component renders.
* See https://storybook.js.org/docs/7.0/angular/api/csf
* to learn how to use render functions.
*/
export const WithAnImage: Story = {
render: () => ({
props: {
src: image.src,
alt: image.alt,
},
template: `<img src="{{src}}" alt="{{alt}}" />`,
}),
};
```

View File

@ -9,12 +9,8 @@ import { MyComponent } from './MyComponent.component';
<!-- Assume image.png is located in the "public" directory.-->
<Story
name="WithAnImage">
{{
props: {
src: '/image.png',
alt: 'my image',
},
}}
</Story>
name="withAnImage"
render={() => ({
template: `<img src="/otherimage.jpg" alt="my image"/>`,
})} />
```

View File

@ -1,24 +1,26 @@
```ts
// MyComponent.stories.ts
import type { Meta, StoryFn } from '@storybook/angular';
import type { Meta, Story } from '@storybook/angular';
import { MyComponent } from './MyComponent.component';
export default {
/* 👇 The title prop is optional.
* See https://storybook.js.org/docs/angular/configure/overview#configure-story-loading
* to learn how to generate automatic titles
*/
* See https://storybook.js.org/docs/7.0/angular/configure/overview#configure-story-loading
* to learn how to generate automatic titles
*/
title: 'img',
component: MyComponent,
} as Meta;
// Assume image.png is located in the "public" directory.
export const WithAnImage: StoryFn = () => ({
props: {
src: '/image.png',
alt: 'my image',
},
});
```
export const WithAnImage: Story = {
render: () => ({
props: {
src: '/image.png',
alt: 'my image',
},
}),
};
```

View File

@ -16,28 +16,27 @@ import { Button } from './Button.component';
}
}} />
export const Template = (args) => ({ props: args });
## This is an accessible story
<Story
name="Accessible"
<Story
name="Accessible"
args={{
primary: false,
label: 'Button'
}}>
{Template.bind({})}
</Story>
}}
render={(args) => ({
props: args,
})} />
## This is not
<Story
name="Inaccessible"
<Story
name="Inaccessible"
args={{
primary: false,
label: 'Button',
backgroundColor: 'red'
}}>
{Template.bind({})}
</Story>
}}
render={(args) => ({
props: args,
})} />
```

View File

@ -1,14 +1,14 @@
```ts
// Button.stories.ts
import type { Meta, StoryFn } from '@storybook/angular';
import type { Meta, Story } from '@storybook/angular';
import { Button } from './Button.component';
export default {
/* 👇 The title prop is optional.
* See https://storybook.js.org/docs/angular/configure/overview#configure-story-loading to learn how to generate automatic titles
*/
* See https://storybook.js.org/docs/7.0/angular/configure/overview#configure-story-loading to learn how to generate automatic titles
*/
title: 'Accessibility testing',
component: Button,
argTypes: {
@ -16,19 +16,18 @@ export default {
},
} as Meta;
const Template: StoryFn = (args) => ({
props: args,
});
export const Accessible: StoryFn = Template.bind({});
Accessible.args = {
primary: false,
label: 'Button',
// This is an accessible story
export const Accessible: Story = {
args: {
primary: false,
label: 'Button',
},
};
export const Inaccessible: StoryFn = Template.bind({});
Inaccessible.args = {
...Accessible.args,
backgroundColor: 'red',
// This is not
export const Inaccessible: Story = {
args: {
...Accessible.args,
backgroundColor: 'red',
},
};
```
```

View File

@ -0,0 +1,41 @@
```ts
// MyComponent.stories.ts
import { Meta, moduleMetadata, Story } from '@storybook/angular';
import { CommonModule } from '@angular/common';
import { Layout } from './Layout.component';
import { MyComponent } from './MyComponent.component';
export default {
/* 👇 The title prop is optional.
* See https://storybook.js.org/docs/7.0/angular/configure/overview#configure-story-loading
* to learn how to generate automatic titles
*/
title: 'MyComponent',
component: MyComponent,
decorators: [
moduleMetadata({
declarations: [Layout],
imports: [CommonModule],
}),
],
} as Meta;
export const Example: Story = {
render: () => ({
template: `
<app-layout>
<header>
<h1>Example</h1>
</header>
<article>
<app-my-component></app-my-component>
</article>
</app-layout>
`,
}),
};
```

View File

@ -1,11 +1,11 @@
```ts
// YourPage.stories.ts
import { Meta, moduleMetadata, Story } from '@storybook/angular';
import { CommonModule } from '@angular/common';
import { HttpClientModule } from '@angular/common/http';
import { Meta, moduleMetadata, StoryFn } from '@storybook/angular';
import { graphql } from 'msw';
import { DocumentScreen } from './YourPage.component';
@ -17,9 +17,9 @@ import { MockGraphQLModule } from './mock-graphql.module';
export default {
/* 👇 The title prop is optional.
* See https://storybook.js.org/docs/angular/configure/overview#configure-story-loading
* to learn how to generate automatic titles
*/
* See https://storybook.js.org/docs/7.0/angular/configure/overview#configure-story-loading
* to learn how to generate automatic titles
*/
title: 'DocumentScreen',
component: DocumentScreen,
decorators: [
@ -79,32 +79,30 @@ const TestData = {
],
};
const PageTemplate: StoryFn = () => ({
props: {},
});
export const MockedSuccess = PageTemplate.bind({});
MockedSuccess.parameters = {
msw: [
graphql.query('AllInfoQuery', (req, res, ctx) => {
return res(ctx.data(TestData));
}),
],
export const MockedSuccess: Story = {
parameters: {
msw: [
graphql.query('AllInfoQuery', (req, res, ctx) => {
return res(ctx.data(TestData));
}),
],
},
};
export const MockedError = PageTemplate.bind({});
MockedError.parameters = {
msw: [
graphql.query('AllInfoQuery', (req, res, ctx) => {
return res(
ctx.delay(800),
ctx.errors([
{
message: 'Access denied',
},
])
);
}),
],
export const MockedError: Story = {
parameters: {
msw: [
graphql.query('AllInfoQuery', (req, res, ctx) => {
return res(
ctx.delay(800),
ctx.errors([
{
message: 'Access denied',
},
])
);
}),
],
},
};
```
```

View File

@ -1,11 +1,11 @@
```ts
// YourPage.stories.ts
import { Meta, moduleMetadata, Story } from '@storybook/angular';
import { CommonModule } from '@angular/common';
import { HttpClientModule } from '@angular/common/http';
import { Meta, moduleMetadata, StoryFn } from '@storybook/angular';
import { rest } from 'msw';
import { DocumentScreen } from './YourPage.component';
@ -15,9 +15,9 @@ import { PageLayout } from './PageLayout.component';
export default {
/* 👇 The title prop is optional.
* See https://storybook.js.org/docs/angular/configure/overview#configure-story-loading
* to learn how to generate automatic titles
*/
* See https://storybook.js.org/docs/7.0/angular/configure/overview#configure-story-loading
* to learn how to generate automatic titles
*/
title: 'DocumentScreen',
component: DocumentScreen,
decorators: [
@ -77,25 +77,23 @@ const TestData = {
],
};
const PageTemplate: StoryFn = () => ({
props: {},
});
export const MockedSuccess = PageTemplate.bind({});
MockedSuccess.parameters = {
msw: [
rest.get('https://your-restful-endpoint', (_req, res, ctx) => {
return res(ctx.json(TestData));
}),
],
export const MockedSuccess: Story = {
parameters: {
msw: [
rest.get('https://your-restful-endpoint', (_req, res, ctx) => {
return res(ctx.json(TestData));
}),
],
},
};
export const MockedError = PageTemplate.bind({});
MockedError.parameters = {
msw: [
rest.get('https://your-restful-endpoint', (_req, res, ctx) => {
return res(ctx.delay(800), ctx.status(403));
}),
],
export const MockedError: Story = {
parameters: {
msw: [
rest.get('https://your-restful-endpoint', (_req, res, ctx) => {
return res(ctx.delay(800), ctx.status(403));
}),
],
},
};
```
```

View File

@ -1,24 +0,0 @@
```ts
// Form.stories.ts
import { userEvent, within } from '@storybook/testing-library';
import { LoginForm } from './LoginForm.component';
export default {
component: LoginForm,
};
export const FilledForm = {
play: async ({ args, canvasElement }) => {
// Starts querying the component from its root element
const canvas = within(canvasElement);
await userEvent.type(canvas.getByTestId('email'), 'email');
await userEvent.type(canvas.getByTestId('password'), 'password');
// See https://storybook.js.org/docs/7.0/angular/essentials/actions#automatically-matching-args to learn how to setup logging in the Actions panel
await userEvent.click(canvas.getByRole('button'));
},
};
```

View File

@ -10,9 +10,9 @@ import { ListItem } from './list-item.component';
export default {
/* 👇 The title prop is optional.
* See https://storybook.js.org/docs/angular/configure/overview#configure-story-loading
* to learn how to generate automatic titles
*/
* See https://storybook.js.org/docs/7.0/angular/configure/overview#configure-story-loading
* to learn how to generate automatic titles
*/
title: 'List',
component: List,
decorators: [
@ -24,26 +24,33 @@ export default {
} as Meta;
// Always an empty list, not super interesting
export const Empty: Story = (args) => ({
props: args,
template: `<app-list></app-list>`,
});
export const Empty: Story = {
render: (args) => ({
props: args,
template: '<app-list></app-list>',
}),
};
export const OneItem: Story = (args) => ({
props: args,
template: `
<app-list>
<app-listitem></app-listitem>
</app-list>`,
});
export const OneItem: Story = {
render: (args) => ({
props: args,
template: `
<app-list>
<app-list-item></app-list-item>
</app-list>`,
}),
};
export const ManyItems: Story = (args) => ({
props: args,
template: `
<app-list>
<app-listitem></app-listitem>
<app-listitem></app-listitem>
<app-listitem></app-listitem>
</app-list>`,
});
export const ManyItems: Story = {
render: (args) => ({
props: args,
template: `
<app-list>
<app-list-item></app-list-item>
<app-list-item></app-list-item>
<app-list-item></app-list-item>
</app-list>
`,
}),
};
```

View File

@ -13,9 +13,9 @@ import { Selected, Unselected } from './ListItem.stories';
export default {
/* 👇 The title prop is optional.
* See https://storybook.js.org/docs/angular/configure/overview#configure-story-loading
* to learn how to generate automatic titles
*/
* See https://storybook.js.org/docs/7.0/angular/configure/overview#configure-story-loading
* to learn how to generate automatic titles
*/
title: 'List',
component: List,
decorators: [
@ -26,19 +26,25 @@ export default {
],
} as Meta;
export const ManyItems: Story = (args) => ({
props: args,
template: `
<app-list>
<app-listitem [isSelected]="Selected"></app-listitem>
<app-listitem [isSelected]="Unselected"></app-listitem>
<app-listitem [isSelected]="Unselected"></app-listitem>
</app-list>
`,
});
ManyItems.args= {
Selected: Selected.args.isSelected,
Unselected: Unselected.args.isSelected,
/*
*👇 Render functions are a framework specific feature to allow you control on how the component renders.
* See https://storybook.js.org/docs/7.0/angular/api/csf
* to learn how to use render functions.
*/
export const ManyItems: Story = {
args: {
Selected: Selected.args.isSelected,
Unselected: Unselected.args.isSelected,
},
render: (args) => ({
props: args,
template: `
<app-list>
<app-list-item [isSelected]="Selected"></app-list-item>
<app-list-item [isSelected]="Unselected"></app-list-item>
<app-list-item [isSelected]="Unselected"></app-list-item>
</app-list>
`,
}),
};
```

View File

@ -9,9 +9,9 @@ import { List } from './list.component';
export default {
/* 👇 The title prop is optional.
* See https://storybook.js.org/docs/angular/configure/overview#configure-story-loading
* to learn how to generate automatic titles
*/
* See https://storybook.js.org/docs/7.0/angular/configure/overview#configure-story-loading
* to learn how to generate automatic titles
*/
component: List,
decorators: [
moduleMetadata({
@ -22,8 +22,10 @@ export default {
} as Meta;
// Always an empty list, not super interesting
const Template: StoryFn = (args) => ({
props: args,
template: `<app-list></app-list>`,
});
```
export const Empty: Story = {
render: (args) => ({
props: args,
template: `<app-list></app-list>`,
}),
};
```

View File

@ -13,9 +13,9 @@ import { Unchecked } from './ListItem.stories';
export default {
/* 👇 The title prop is optional.
* See https://storybook.js.org/docs/angular/configure/overview#configure-story-loading
* to learn how to generate automatic titles
*/
* See https://storybook.js.org/docs/7.0/angular/configure/overview#configure-story-loading
* to learn how to generate automatic titles
*/
title: 'List',
component: List,
decorators: [
@ -26,29 +26,33 @@ export default {
],
} as Meta;
const ListTemplate: Story = (args) => ({
props: args,
template: `
<app-list>
<div *ngFor="let item of items">
<app-list-item [item]="item"></app-list-item>
</div>
</app-list>
`,
});
export const Empty = ListTemplate.bind({});
EmptyListTemplate.args = {
items: [],
/*
*👇 Render functions are a framework specific feature to allow you control on how the component renders.
* See https://storybook.js.org/docs/7.0/angular/api/csf
* to learn how to use render functions.
*/
const ListTemplate: Story = {
render: (args) => ({
props: args,
template: `
<app-list>
<div *ngFor="let item of items">
<app-list-item [item]="item"></app-list-item>
</div>
</app-list>
`,
}),
};
export const OneItem = ListTemplate.bind({});
OneItem.args = {
items: [
{
...Unchecked.args,
},
],
export const Empty: Story = {
...ListTemplate,
args: { items: [] },
};
export const OneItem: Story = {
...ListTemplate,
args: {
items: [{ ...Unchecked.args }],
},
};
```

View File

@ -13,9 +13,9 @@ import { Unchecked } from './ListItem.stories';
export default {
/* 👇 The title prop is optional.
* See https://storybook.js.org/docs/angular/configure/overview#configure-story-loading
* to learn how to generate automatic titles
*/
* See https://storybook.js.org/docs/7.0/angular/configure/overview#configure-story-loading
* to learn how to generate automatic titles
*/
title: 'List',
component: List,
decorators: [
@ -26,17 +26,22 @@ export default {
],
} as Meta;
export const OneItem: Story = (args) => ({
props: args,
template: `
<app-list>
<app-list-item [item]="item"></app-list-item>
</app-list>
`,
});
OneItem.args = {
...Unchecked.args,
/*
*👇 Render functions are a framework specific feature to allow you control on how the component renders.
* See https://storybook.js.org/docs/7.0/angular/api/csf
* to learn how to use render functions.
*/
export const OneItem: Story = {
render: (args) => ({
props: args,
template: `
<app-list>
<app-list-item [item]="item"></app-list-item>
</app-list>
`,
}),
args: {
...Unchecked.args,
},
};
```

View File

@ -10,9 +10,9 @@ import { ListItem } from './list-item.component';
export default {
/* 👇 The title prop is optional.
* See https://storybook.js.org/docs/angular/configure/overview#configure-story-loading
* to learn how to generate automatic titles
*/
* See https://storybook.js.org/docs/7.0/angular/configure/overview#configure-story-loading
* to learn how to generate automatic titles
*/
title: 'List',
component: List,
subcomponents: { ListItem }, //👈 Adds the ListItem component as a subcomponent
@ -24,20 +24,22 @@ export default {
],
} as Meta;
export const Empty: StoryFn = () => ({
props: {
args,
},
});
/*
*👇 Render functions are a framework specific feature to allow you control on how the component renders.
* See https://storybook.js.org/docs/7.0/angular/api/csf
* to learn how to use render functions.
*/
export const Empty: Story = {};
export const OneItem: StoryFn = () => ({
props: {
args,
},
template: `
<app-list>
<app-list-item></app-list-item>
</app-list>
export const OneItem: Story = {
args: {},
render: (args) => ({
props: args,
template: `
<app-list>
<app-list-item></app-list-item>
</app-list>
`,
});
```
}),
};
```

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