diff --git a/.circleci/config.yml b/.circleci/config.yml index 372652ee4264..6dcb72899d0d 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -277,9 +277,9 @@ jobs: - run: name: run e2e tests cra command: yarn test:e2e-framework --pnp cra - - run: - name: run e2e tests vue - command: yarn test:e2e-framework --pnp sfcVue + # - run: + # name: run e2e tests vue + # command: yarn test:e2e-framework --pnp sfcVue - run: name: prep artifacts when: always diff --git a/README.md b/README.md index 0472ab5a1acf..df9b875b9e3f 100644 --- a/README.md +++ b/README.md @@ -51,8 +51,8 @@ It allows you to browse a component library, view the different states of each c

View README for:
- latest - next + latest + next

## Table of contents @@ -92,19 +92,19 @@ For additional help, join us in the [Storybook Discord](https://discord.gg/story ### Supported Frameworks -| Framework | Demo | | -| -------------------------------------------------------------- | ------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------- | -| [React](app/react) | [v6.4.x](https://storybookjs.netlify.com/official-storybook/?path=/story/*) | [![React](https://img.shields.io/npm/dm/@storybook/react.svg)](app/react) | -| [Vue](app/vue) | [v6.4.x](https://storybookjs.netlify.com/vue-kitchen-sink/) | [![Vue](https://img.shields.io/npm/dm/@storybook/vue.svg)](app/vue) | -| [Angular](app/angular) | [v6.4.x](https://storybookjs.netlify.com/angular-cli/) | [![Angular](https://img.shields.io/npm/dm/@storybook/angular.svg)](app/angular) | -| [Web components](app/web-components) | [v6.4.x](https://storybookjs.netlify.com/web-components-kitchen-sink/) | [![Svelte](https://img.shields.io/npm/dm/@storybook/web-components.svg)](app/web-components) | -| [React Native](https://github.com/storybookjs/react-native) | - | [![React Native](https://img.shields.io/npm/dm/@storybook/react-native.svg)](https://github.com/storybookjs/react-native) | -| [HTML](app/html) | [v6.4.x](https://storybookjs.netlify.com/html-kitchen-sink/) | [![HTML](https://img.shields.io/npm/dm/@storybook/html.svg)](app/html) | -| [Ember](app/ember) | [v6.4.x](https://storybookjs.netlify.com/ember-cli/) | [![Ember](https://img.shields.io/npm/dm/@storybook/ember.svg)](app/ember) | -| [Svelte](app/svelte) | [v6.4.x](https://storybookjs.netlify.com/svelte-kitchen-sink/) | [![Svelte](https://img.shields.io/npm/dm/@storybook/svelte.svg)](app/svelte) | -| [Preact](app/preact) | [v6.4.x](https://storybookjs.netlify.com/preact-kitchen-sink/) | [![Preact](https://img.shields.io/npm/dm/@storybook/preact.svg)](app/preact) | -| [Marionette.js](https://github.com/storybookjs/marionette) | - | [![Marionette.js](https://img.shields.io/npm/dm/@storybook/marionette.svg)](https://github.com/storybookjs/marionette) | -| [Android, iOS, Flutter](https://github.com/storybookjs/native) | [v6.4.x](https://storybookjs.github.io/native/@storybook/native-flutter-example/index.html) | [![Native](https://img.shields.io/npm/dm/@storybook/native.svg)](https://github.com/storybookjs/native) | +| Framework | Demo | | +| -------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- | +| [React](app/react) | [![Storybook demo](https://img.shields.io/npm/v/@storybook/react/latest?style=flat-square&color=blue&label)](https://storybookjs.netlify.com/official-storybook/?path=/story/*) | [![React](https://img.shields.io/npm/dm/@storybook/react?style=flat-square&color=eee)](app/react) | +| [Vue](app/vue) | [![Storybook demo](https://img.shields.io/npm/v/@storybook/vue/latest?style=flat-square&color=blue&label)](https://storybookjs.netlify.com/vue-kitchen-sink/) | [![Vue](https://img.shields.io/npm/dm/@storybook/vue?style=flat-square&color=eee)](app/vue) | +| [Angular](app/angular) | [![Storybook demo](https://img.shields.io/npm/v/@storybook/angular/latest?style=flat-square&color=blue&label)](https://storybookjs.netlify.com/angular-cli/) | [![Angular](https://img.shields.io/npm/dm/@storybook/angular?style=flat-square&color=eee)](app/angular) | +| [Web components](app/web-components) | [![Storybook demo](https://img.shields.io/npm/v/@storybook/web-components/latest?style=flat-square&color=blue&label)](https://storybookjs.netlify.com/web-components-kitchen-sink/) | [![Svelte](https://img.shields.io/npm/dm/@storybook/web-components?style=flat-square&color=eee)](app/web-components) | +| [React Native](https://github.com/storybookjs/react-native) | - | [![React Native](https://img.shields.io/npm/dm/@storybook/react-native?style=flat-square&color=eee)](https://github.com/storybookjs/react-native) | +| [HTML](app/html) | [![Storybook demo](https://img.shields.io/npm/v/@storybook/html/latest?style=flat-square&color=blue&label)](https://storybookjs.netlify.com/html-kitchen-sink/) | [![HTML](https://img.shields.io/npm/dm/@storybook/html?style=flat-square&color=eee)](app/html) | +| [Ember](app/ember) | [![Storybook demo](https://img.shields.io/npm/v/@storybook/ember/latest?style=flat-square&color=blue&label)](https://storybookjs.netlify.com/ember-cli/) | [![Ember](https://img.shields.io/npm/dm/@storybook/ember?style=flat-square&color=eee)](app/ember) | +| [Svelte](app/svelte) | [![Storybook demo](https://img.shields.io/npm/v/@storybook/svelte/latest?style=flat-square&color=blue&label)](https://storybookjs.netlify.com/svelte-kitchen-sink/) | [![Svelte](https://img.shields.io/npm/dm/@storybook/svelte?style=flat-square&color=eee)](app/svelte) | +| [Preact](app/preact) | [![Storybook demo](https://img.shields.io/npm/v/@storybook/preact/latest?style=flat-square&color=blue&label)](https://storybookjs.netlify.com/preact-kitchen-sink/) | [![Preact](https://img.shields.io/npm/dm/@storybook/preact?style=flat-square&color=eee)](app/preact) | +| [Marionette.js](https://github.com/storybookjs/marionette) | - | [![Marionette.js](https://img.shields.io/npm/dm/@storybook/marionette?style=flat-square&color=eee)](https://github.com/storybookjs/marionette) | +| [Android, iOS, Flutter](https://github.com/storybookjs/native) | [![Storybook demo](https://img.shields.io/npm/v/@storybook/native/latest?style=flat-square&color=blue&label)](https://storybookjs.github.io/native/@storybook/native-flutter-example/index.html) | [![Native](https://img.shields.io/npm/dm/@storybook/native?style=flat-square&color=eee)](https://github.com/storybookjs/native) | ### Sub Projects diff --git a/SECURITY.md b/SECURITY.md index 721021f54540..04845f5bf4a8 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -2,9 +2,9 @@ ## Supported Versions -| Version | Supported | -| ---------- | ------------------ | -| 6.3, 6.4 | :white_check_mark: | +| Version | Supported | +| --------------- | ------------------ | +| 6.3, 6.4, 6.5 | :white_check_mark: | ## Reporting a Vulnerability diff --git a/addons/a11y/src/components/VisionSimulator.test.tsx b/addons/a11y/src/components/VisionSimulator.test.tsx index 51b41cdba5ca..9191e058db6f 100644 --- a/addons/a11y/src/components/VisionSimulator.test.tsx +++ b/addons/a11y/src/components/VisionSimulator.test.tsx @@ -30,7 +30,7 @@ describe('Vision Simulator', () => { await waitFor(() => expect(screen.getByTitle('Vision simulator')).toBeInTheDocument()); }); - it('should display tooltip on click', async () => { + it.skip('should display tooltip on click', async () => { // given render(); await waitFor(() => expect(screen.getByTitle('Vision simulator')).toBeInTheDocument()); @@ -45,7 +45,7 @@ describe('Vision Simulator', () => { ); }); - it('should set filter', async () => { + it.skip('should set filter', async () => { // given render(); await waitFor(() => expect(screen.getByTitle('Vision simulator')).toBeInTheDocument()); diff --git a/addons/interactions/package.json b/addons/interactions/package.json index d86a5ae3e0f2..a9cdfc2204d0 100644 --- a/addons/interactions/package.json +++ b/addons/interactions/package.json @@ -59,7 +59,7 @@ }, "devDependencies": { "@storybook/jest": "^0.0.5", - "@storybook/testing-library": "^0.0.7", + "@storybook/testing-library": "0.0.14-next.0", "formik": "^2.2.9" }, "peerDependencies": { diff --git a/addons/interactions/src/Panel.stories.tsx b/addons/interactions/src/Panel.stories.tsx index 8e22606d4ecf..cc6f37afdd09 100644 --- a/addons/interactions/src/Panel.stories.tsx +++ b/addons/interactions/src/Panel.stories.tsx @@ -4,7 +4,7 @@ import { ComponentStoryObj, ComponentMeta } from '@storybook/react'; import { CallStates } from '@storybook/instrumenter'; import { styled } from '@storybook/theming'; -import { getCall } from './mocks'; +import { getCalls, getInteractions } from './mocks'; import { AddonPanelPure } from './Panel'; import SubnavStories from './components/Subnav/Subnav.stories'; @@ -20,6 +20,8 @@ const StyledWrapper = styled.div(({ theme }) => ({ overflow: 'auto', })); +const interactions = getInteractions(CallStates.DONE); + export default { title: 'Addons/Interactions/Panel', component: AddonPanelPure, @@ -34,10 +36,10 @@ export default { layout: 'fullscreen', }, args: { - calls: new Map(), + calls: new Map(getCalls(CallStates.DONE).map((call) => [call.id, call])), controls: SubnavStories.args.controls, controlStates: SubnavStories.args.controlStates, - interactions: [getCall(CallStates.DONE)], + interactions, fileName: 'addon-interactions.stories.tsx', hasException: false, isPlaying: false, @@ -52,14 +54,14 @@ type Story = ComponentStoryObj; export const Passing: Story = { args: { - interactions: [getCall(CallStates.DONE)], + interactions: getInteractions(CallStates.DONE), }, }; export const Paused: Story = { args: { isPlaying: true, - interactions: [getCall(CallStates.WAITING)], + interactions: getInteractions(CallStates.WAITING), controlStates: { debugger: true, start: false, @@ -68,20 +70,21 @@ export const Paused: Story = { next: true, end: true, }, + pausedAt: interactions[interactions.length - 1].id, }, }; export const Playing: Story = { args: { isPlaying: true, - interactions: [getCall(CallStates.ACTIVE)], + interactions: getInteractions(CallStates.ACTIVE), }, }; export const Failed: Story = { args: { hasException: true, - interactions: [getCall(CallStates.ERROR)], + interactions: getInteractions(CallStates.ERROR), }, }; diff --git a/addons/interactions/src/Panel.tsx b/addons/interactions/src/Panel.tsx index 4693f8577991..0b8325166ace 100644 --- a/addons/interactions/src/Panel.tsx +++ b/addons/interactions/src/Panel.tsx @@ -28,10 +28,16 @@ interface InteractionsPanelProps { active: boolean; controls: Controls; controlStates: ControlStates; - interactions: (Call & { status?: CallStates })[]; + interactions: (Call & { + status?: CallStates; + childCallIds: Call['id'][]; + isCollapsed: boolean; + toggleCollapsed: () => void; + })[]; fileName?: string; hasException?: boolean; isPlaying?: boolean; + pausedAt?: Call['id']; calls: Map; endRef?: React.Ref; onScrollToEnd?: () => void; @@ -66,6 +72,7 @@ export const AddonPanelPure: React.FC = React.memo( fileName, hasException, isPlaying, + pausedAt, onScrollToEnd, endRef, isRerunAnimating, @@ -87,15 +94,21 @@ export const AddonPanelPure: React.FC = React.memo( setIsRerunAnimating={setIsRerunAnimating} /> )} - {interactions.map((call) => ( - - ))} +
+ {interactions.map((call) => ( + + ))} +
{!isPlaying && interactions.length === 0 && ( @@ -116,17 +129,17 @@ export const AddonPanelPure: React.FC = React.memo( export const Panel: React.FC = (props) => { const [storyId, setStoryId] = React.useState(); const [controlStates, setControlStates] = React.useState(INITIAL_CONTROL_STATES); + const [pausedAt, setPausedAt] = React.useState(); const [isPlaying, setPlaying] = React.useState(false); const [isRerunAnimating, setIsRerunAnimating] = React.useState(false); const [scrollTarget, setScrollTarget] = React.useState(); + const [collapsed, setCollapsed] = React.useState>(new Set()); + const [log, setLog] = React.useState([]); // Calls are tracked in a ref so we don't needlessly rerender. const calls = React.useRef>>(new Map()); const setCall = ({ status, ...call }: Call) => calls.current.set(call.id, call); - const [log, setLog] = React.useState([]); - const interactions = log.map(({ callId, status }) => ({ ...calls.current.get(callId), status })); - const endRef = React.useRef(); React.useEffect(() => { let observer: IntersectionObserver; @@ -146,10 +159,12 @@ export const Panel: React.FC = (props) => { [EVENTS.SYNC]: (payload) => { setControlStates(payload.controlStates); setLog(payload.logItems); + setPausedAt(payload.pausedAt); }, [STORY_RENDER_PHASE_CHANGED]: (event) => { setStoryId(event.storyId); setPlaying(event.newPhase === 'playing'); + setPausedAt(undefined); }, }, [] @@ -177,6 +192,38 @@ export const Panel: React.FC = (props) => { const showStatus = log.length > 0 && !isPlaying; const hasException = log.some((item) => item.status === CallStates.ERROR); + const interactions = React.useMemo(() => { + const callsById = new Map(); + const childCallMap = new Map(); + return log + .filter(({ callId, parentId }) => { + if (!parentId) return true; + childCallMap.set(parentId, (childCallMap.get(parentId) || []).concat(callId)); + return !collapsed.has(parentId); + }) + .map(({ callId, status }) => ({ ...calls.current.get(callId), status } as Call)) + .map((call) => { + const status = + call.status === CallStates.ERROR && + callsById.get(call.parentId)?.status === CallStates.ACTIVE + ? CallStates.ACTIVE + : call.status; + callsById.set(call.id, { ...call, status }); + return { + ...call, + status, + childCallIds: childCallMap.get(call.id), + isCollapsed: collapsed.has(call.id), + toggleCollapsed: () => + setCollapsed((ids) => { + if (ids.has(call.id)) ids.delete(call.id); + else ids.add(call.id); + return new Set(ids); + }), + }; + }); + }, [log, collapsed]); + return ( @@ -191,6 +238,7 @@ export const Panel: React.FC = (props) => { fileName={fileName} hasException={hasException} isPlaying={isPlaying} + pausedAt={pausedAt} endRef={endRef} onScrollToEnd={scrollTarget && scrollToTarget} isRerunAnimating={isRerunAnimating} diff --git a/addons/interactions/src/components/AccountForm/addon-interactions.stories.tsx b/addons/interactions/src/components/AccountForm/addon-interactions.stories.tsx index 9619a228b507..f1d8aace3951 100644 --- a/addons/interactions/src/components/AccountForm/addon-interactions.stories.tsx +++ b/addons/interactions/src/components/AccountForm/addon-interactions.stories.tsx @@ -35,6 +35,12 @@ export const Demo: CSF2Story = (args) => ( Demo.play = async ({ args, canvasElement }) => { await userEvent.click(within(canvasElement).getByRole('button')); await expect(args.onSubmit).toHaveBeenCalledWith(expect.stringMatching(/([A-Z])\w+/gi)); + await expect([{ name: 'John', age: 42 }]).toEqual( + expect.arrayContaining([ + expect.objectContaining({ name: 'John' }), + expect.objectContaining({ age: 42 }), + ]) + ); }; export const FindBy: CSF2Story = (args) => { @@ -131,7 +137,7 @@ export const StandardEmailFailed: CSF3Story = { await userEvent.click(canvas.getByRole('button', { name: /create account/i })); await canvas.findByText('Please enter a correctly formatted email address'); - expect(args.onSubmit).not.toHaveBeenCalled(); + await expect(args.onSubmit).not.toHaveBeenCalled(); }, }; diff --git a/addons/interactions/src/components/Interaction/Interaction.stories.tsx b/addons/interactions/src/components/Interaction/Interaction.stories.tsx index 3fc5ab83b5ef..2089cef4a2a0 100644 --- a/addons/interactions/src/components/Interaction/Interaction.stories.tsx +++ b/addons/interactions/src/components/Interaction/Interaction.stories.tsx @@ -2,7 +2,7 @@ import { ComponentStoryObj, ComponentMeta } from '@storybook/react'; import { expect } from '@storybook/jest'; import { CallStates } from '@storybook/instrumenter'; import { userEvent, within } from '@storybook/testing-library'; -import { getCall } from '../../mocks'; +import { getCalls } from '../../mocks'; import { Interaction } from './Interaction'; import SubnavStories from '../Subnav/Subnav.stories'; @@ -13,7 +13,7 @@ export default { title: 'Addons/Interactions/Interaction', component: Interaction, args: { - callsById: new Map(), + callsById: new Map(getCalls(CallStates.DONE).map((call) => [call.id, call])), controls: SubnavStories.args.controls, controlStates: SubnavStories.args.controlStates, }, @@ -21,25 +21,31 @@ export default { export const Active: Story = { args: { - call: getCall(CallStates.ACTIVE), + call: getCalls(CallStates.ACTIVE).slice(-1)[0], }, }; export const Waiting: Story = { args: { - call: getCall(CallStates.WAITING), + call: getCalls(CallStates.WAITING).slice(-1)[0], }, }; export const Failed: Story = { args: { - call: getCall(CallStates.ERROR), + call: getCalls(CallStates.ERROR).slice(-1)[0], }, }; export const Done: Story = { args: { - call: getCall(CallStates.DONE), + call: getCalls(CallStates.DONE).slice(-1)[0], + }, +}; + +export const WithParent: Story = { + args: { + call: { ...getCalls(CallStates.DONE).slice(-1)[0], parentId: 'parent-id' }, }, }; diff --git a/addons/interactions/src/components/Interaction/Interaction.tsx b/addons/interactions/src/components/Interaction/Interaction.tsx index d9d6bf27ddb1..30922f8dc908 100644 --- a/addons/interactions/src/components/Interaction/Interaction.tsx +++ b/addons/interactions/src/components/Interaction/Interaction.tsx @@ -1,4 +1,5 @@ import * as React from 'react'; +import { IconButton, Icons, TooltipNote, WithTooltip } from '@storybook/components'; import { Call, CallStates, ControlStates } from '@storybook/instrumenter'; import { styled, typography } from '@storybook/theming'; import { transparentize } from 'polished'; @@ -15,23 +16,55 @@ const MethodCallWrapper = styled.div(() => ({ inlineSize: 'calc( 100% - 40px )', })); -const RowContainer = styled('div', { shouldForwardProp: (prop) => !['call'].includes(prop) })<{ - call: Call; -}>(({ theme, call }) => ({ - display: 'flex', - flexDirection: 'column', - borderBottom: `1px solid ${theme.appBorderColor}`, - fontFamily: typography.fonts.base, - fontSize: 13, - ...(call.status === CallStates.ERROR && { - backgroundColor: - theme.base === 'dark' ? transparentize(0.93, theme.color.negative) : theme.background.warning, +const RowContainer = styled('div', { + shouldForwardProp: (prop) => !['call', 'pausedAt'].includes(prop), +})<{ call: Call; pausedAt: Call['id'] }>( + ({ theme, call }) => ({ + position: 'relative', + display: 'flex', + flexDirection: 'column', + borderBottom: `1px solid ${theme.appBorderColor}`, + fontFamily: typography.fonts.base, + fontSize: 13, + ...(call.status === CallStates.ERROR && { + backgroundColor: + theme.base === 'dark' + ? transparentize(0.93, theme.color.negative) + : theme.background.warning, + }), + paddingLeft: call.parentId ? 20 : 0, }), + ({ theme, call, pausedAt }) => + pausedAt === call.id && { + '&::before': { + content: '""', + position: 'absolute', + top: -5, + zIndex: 1, + borderTop: '4.5px solid transparent', + borderLeft: `7px solid ${theme.color.warning}`, + borderBottom: '4.5px solid transparent', + }, + '&::after': { + content: '""', + position: 'absolute', + top: -1, + zIndex: 1, + width: '100%', + borderTop: `1.5px solid ${theme.color.warning}`, + }, + } +); + +const RowHeader = styled.div<{ disabled: boolean }>(({ theme, disabled }) => ({ + display: 'flex', + '&:hover': disabled ? {} : { background: theme.background.hoverable }, })); const RowLabel = styled('button', { shouldForwardProp: (prop) => !['call'].includes(prop) })< React.ButtonHTMLAttributes & { call: Call } >(({ theme, disabled, call }) => ({ + flex: 1, display: 'grid', background: 'none', border: 0, @@ -42,7 +75,6 @@ const RowLabel = styled('button', { shouldForwardProp: (prop) => !['call'].inclu padding: '8px 15px', textAlign: 'start', cursor: disabled || call.status === CallStates.ERROR ? 'default' : 'pointer', - '&:hover': disabled ? {} : { background: theme.background.hoverable }, '&:focus-visible': { outline: 0, boxShadow: `inset 3px 0 0 0 ${ @@ -55,45 +87,101 @@ const RowLabel = styled('button', { shouldForwardProp: (prop) => !['call'].inclu }, })); -const RowMessage = styled('pre')({ - margin: 0, - padding: '8px 10px 8px 30px', +const RowActions = styled.div(({ theme }) => ({ + padding: 6, +})); + +export const StyledIconButton = styled(IconButton as any)(({ theme }) => ({ + color: theme.color.mediumdark, + margin: '0 3px', +})); + +const Note = styled(TooltipNote)(({ theme }) => ({ + fontFamily: theme.typography.fonts.base, +})); + +const RowMessage = styled('div')(({ theme }) => ({ + padding: '8px 10px 8px 36px', fontSize: typography.size.s1, -}); + pre: { + margin: 0, + padding: 0, + }, + p: { + color: theme.color.dark, + }, +})); + +const Exception = ({ exception }: { exception: Call['exception'] }) => { + if (exception.message.startsWith('expect(')) { + return ; + } + const paragraphs = exception.message.split('\n\n'); + const more = paragraphs.length > 1; + return ( + +
{paragraphs[0]}
+ {more &&

See the full stack trace in the browser console.

} +
+ ); +}; export const Interaction = ({ call, callsById, controls, controlStates, + childCallIds, + isCollapsed, + toggleCollapsed, + pausedAt, }: { call: Call; callsById: Map; controls: Controls; controlStates: ControlStates; + childCallIds?: Call['id'][]; + isCollapsed: boolean; + toggleCollapsed: () => void; + pausedAt?: Call['id']; }) => { const [isHovered, setIsHovered] = React.useState(false); return ( - - controls.goto(call.id)} - disabled={!controlStates.goto} - onMouseEnter={() => controlStates.goto && setIsHovered(true)} - onMouseLeave={() => controlStates.goto && setIsHovered(false)} - > - - - - - - {call.status === CallStates.ERROR && - call.exception && - (call.exception.message.startsWith('expect(') ? ( - - ) : ( - {call.exception.message} - ))} + + + controls.goto(call.id)} + disabled={!controlStates.goto || !call.interceptable || !!call.parentId} + onMouseEnter={() => controlStates.goto && setIsHovered(true)} + onMouseLeave={() => controlStates.goto && setIsHovered(false)} + > + + + + + + + {childCallIds?.length > 0 && ( + + } + > + + + + + )} + + + + {call.status === CallStates.ERROR && call.exception?.callId === call.id && ( + + )} ); }; diff --git a/addons/interactions/src/components/MatcherResult.tsx b/addons/interactions/src/components/MatcherResult.tsx index cf52a920ae42..4e3814702e3f 100644 --- a/addons/interactions/src/components/MatcherResult.tsx +++ b/addons/interactions/src/components/MatcherResult.tsx @@ -50,7 +50,7 @@ export const MatcherResult = ({ message }: { message: string }) => {
diff --git a/addons/interactions/src/components/MethodCall.stories.tsx b/addons/interactions/src/components/MethodCall.stories.tsx
index feda43c8ff5c..b65001b4e1cb 100644
--- a/addons/interactions/src/components/MethodCall.stories.tsx
+++ b/addons/interactions/src/components/MethodCall.stories.tsx
@@ -27,7 +27,6 @@ export default {
   },
 };
 
-class FooBar {}
 export const Args = () => (
   
@@ -56,37 +55,49 @@ export const Args = () => ( }} showObjectInspector /> - - + + - - - - - - - - - - {/* eslint-disable-next-line symbol-description */} - - + + + + + + + + + + +
); const calls: Call[] = [ { + cursor: 0, id: '1', path: ['screen'], method: 'getByText', @@ -96,6 +107,7 @@ const calls: Call[] = [ retain: false, }, { + cursor: 1, id: '2', path: ['userEvent'], method: 'click', @@ -105,6 +117,7 @@ const calls: Call[] = [ retain: false, }, { + cursor: 2, id: '3', path: [], method: 'expect', @@ -114,6 +127,7 @@ const calls: Call[] = [ retain: false, }, { + cursor: 3, id: '4', path: [{ __callId__: '3' }, 'not'], method: 'toBe', @@ -123,15 +137,17 @@ const calls: Call[] = [ retain: false, }, { + cursor: 4, id: '5', path: ['jest'], method: 'fn', storyId: 'kind--story', - args: [function actionHandler() {}], + args: [{ __function__: { name: 'actionHandler' } }], interceptable: false, retain: false, }, { + cursor: 5, id: '6', path: [], method: 'expect', @@ -141,20 +157,28 @@ const calls: Call[] = [ retain: false, }, { + cursor: 6, id: '7', path: ['expect'], method: 'stringMatching', storyId: 'kind--story', - args: [/hello/i], + args: [{ __regexp__: { flags: 'i', source: 'hello' } }], interceptable: false, retain: false, }, { + cursor: 7, id: '8', path: [{ __callId__: '6' }, 'not'], method: 'toHaveBeenCalledWith', storyId: 'kind--story', - args: [{ __callId__: '7' }, new Error("Cannot read property 'foo' of undefined")], + args: [ + { __callId__: '7' }, + [ + { __error__: { name: 'Error', message: "Cannot read property 'foo' of undefined" } }, + { __symbol__: { description: 'Hello world' } }, + ], + ], interceptable: false, retain: false, }, diff --git a/addons/interactions/src/components/MethodCall.tsx b/addons/interactions/src/components/MethodCall.tsx index 10a3bf2c0f47..871068cea0ef 100644 --- a/addons/interactions/src/components/MethodCall.tsx +++ b/addons/interactions/src/components/MethodCall.tsx @@ -111,32 +111,34 @@ export const Node = ({ return ; case value === undefined: return ; + case Array.isArray(value): + return ; case typeof value === 'string': - return ; + return ; case typeof value === 'number': - return ; + return ; case typeof value === 'boolean': - return ; - case typeof value === 'function': - return ; - case value instanceof Array: - return ; - case value instanceof Date: - return ; - case value instanceof Error: - return ; - case value instanceof RegExp: - return ; + return ; + + /* eslint-disable no-underscore-dangle */ + case Object.prototype.hasOwnProperty.call(value, '__date__'): + return ; + case Object.prototype.hasOwnProperty.call(value, '__error__'): + return ; + case Object.prototype.hasOwnProperty.call(value, '__regexp__'): + return ; + case Object.prototype.hasOwnProperty.call(value, '__function__'): + return ; + case Object.prototype.hasOwnProperty.call(value, '__symbol__'): + return ; case Object.prototype.hasOwnProperty.call(value, '__element__'): - // eslint-disable-next-line no-underscore-dangle - return ; + return ; + case Object.prototype.hasOwnProperty.call(value, '__class__'): + return ; case Object.prototype.hasOwnProperty.call(value, '__callId__'): - // eslint-disable-next-line no-underscore-dangle return ; - case typeof value === 'object' && - value.constructor?.name && - value.constructor?.name !== 'Object': - return ; + /* eslint-enable no-underscore-dangle */ + case Object.prototype.toString.call(value) === '[object Object]': return ; default: @@ -189,12 +191,22 @@ export const BooleanNode = ({ value, ...props }: { value: boolean }) => { ); }; -export const ArrayNode = ({ value, nested = false }: { value: any[]; nested?: boolean }) => { +export const ArrayNode = ({ + value, + nested = false, + callsById, +}: { + value: any[]; + nested?: boolean; + callsById?: Map; +}) => { const colors = useThemeColors(); if (nested) { return […]; } - const nodes = value.slice(0, 3).map((v) => ); + const nodes = value + .slice(0, 3) + .map((v) => ); const nodelist = interleave(nodes, , ); if (value.length <= 3) { return [{nodelist}]; @@ -263,18 +275,27 @@ export const ObjectNode = ({ ); }; -export const ClassNode = ({ value }: { value: Record }) => { +export const ClassNode = ({ name }: { name: string }) => { const colors = useThemeColors(); - return {value.constructor.name}; + return {name}; }; -export const FunctionNode = ({ value }: { value: Function }) => { +export const FunctionNode = ({ name }: { name: string }) => { const colors = useThemeColors(); - return {value.name || 'anonymous'}; + return name ? ( + {name} + ) : ( + anonymous + ); }; -export const ElementNode = ({ value }: { value: ElementRef['__element__'] }) => { - const { prefix, localName, id, classNames = [], innerText } = value; +export const ElementNode = ({ + prefix, + localName, + id, + classNames = [], + innerText, +}: ElementRef['__element__']) => { const name = prefix ? `${prefix}:${localName}` : localName; const colors = useThemeColors(); return ( @@ -309,8 +330,8 @@ export const ElementNode = ({ value }: { value: ElementRef['__element__'] }) => ); }; -export const DateNode = ({ value }: { value: Date }) => { - const [date, time, ms] = value.toISOString().split(/[T.Z]/); +export const DateNode = ({ value }: { value: string }) => { + const [date, time, ms] = value.split(/[T.Z]/); const colors = useThemeColors(); return ( @@ -323,42 +344,36 @@ export const DateNode = ({ value }: { value: Date }) => { ); }; -export const ErrorNode = ({ value }: { value: Error }) => { +export const ErrorNode = ({ name, message }: { name: string; message: string }) => { const colors = useThemeColors(); return ( - {value.name} - {value.message && ': '} - {value.message && ( - 50 ? value.message : ''} - > - {ellipsize(value.message, 50)} + {name} + {message && ': '} + {message && ( + 50 ? message : ''}> + {ellipsize(message, 50)} )} ); }; -export const RegExpNode = ({ value }: { value: RegExp }) => { +export const RegExpNode = ({ flags, source }: { flags: string; source: string }) => { const colors = useThemeColors(); return ( - /{value.source}/{value.flags} + /{source}/{flags} ); }; -export const SymbolNode = ({ value }: { value: symbol }) => { +export const SymbolNode = ({ description }: { description: string }) => { const colors = useThemeColors(); return ( Symbol( - {value.description && ( - {JSON.stringify(value.description)} - )} - ) + {description && "{description}"}) ); }; diff --git a/addons/interactions/src/components/Subnav/Subnav.stories.tsx b/addons/interactions/src/components/Subnav/Subnav.stories.tsx index 9605bc53252c..40e365d03fb9 100644 --- a/addons/interactions/src/components/Subnav/Subnav.stories.tsx +++ b/addons/interactions/src/components/Subnav/Subnav.stories.tsx @@ -12,6 +12,7 @@ export default { goto: action('goto'), next: action('next'), end: action('end'), + rerun: action('rerun'), }, controlStates: { debugger: true, diff --git a/addons/interactions/src/mocks/index.ts b/addons/interactions/src/mocks/index.ts index 7952b6ecf896..e55fe4d88b8f 100644 --- a/addons/interactions/src/mocks/index.ts +++ b/addons/interactions/src/mocks/index.ts @@ -1,31 +1,122 @@ import { CallStates, Call } from '@storybook/instrumenter'; -export const getCall = (status: CallStates): Call => { - const defaultData = { - id: 'addons-interactions-accountform--standard-email-filled [3] change', - cursor: 0, - path: ['fireEvent'], - method: 'change', - storyId: 'addons-interactions-accountform--standard-email-filled', - args: [ - { - __callId__: 'addons-interactions-accountform--standard-email-filled [2] getByTestId', - retain: false, - }, - { - target: { - value: 'michael@chromatic.com', - }, - }, - ], - interceptable: true, - retain: false, - status, - }; +export const getCalls = (finalStatus: CallStates) => { + const calls: Call[] = [ + { + id: 'story--id [3] within', + storyId: 'story--id', + cursor: 3, + path: [], + method: 'within', + args: [{ __element__: { localName: 'div', id: 'root' } }], + interceptable: false, + retain: false, + status: CallStates.DONE, + }, + { + id: 'story--id [4] findByText', + storyId: 'story--id', + cursor: 4, + path: [{ __callId__: 'story--id [3] within' }], + method: 'findByText', + args: ['Click'], + interceptable: true, + retain: false, + status: CallStates.DONE, + }, + { + id: 'story--id [5] click', + storyId: 'story--id', + cursor: 5, + path: ['userEvent'], + method: 'click', + args: [{ __element__: { localName: 'button', innerText: 'Click' } }], + interceptable: true, + retain: false, + status: CallStates.DONE, + }, + { + id: 'story--id [6] waitFor', + storyId: 'story--id', + cursor: 6, + path: [], + method: 'waitFor', + args: [{ __function__: { name: '' } }], + interceptable: true, + retain: false, + status: CallStates.DONE, + }, + { + id: 'story--id [6] waitFor [0] expect', + parentId: 'story--id [6] waitFor', + storyId: 'story--id', + cursor: 1, + path: [], + method: 'expect', + args: [{ __function__: { name: 'handleSubmit' } }], + interceptable: false, + retain: false, + status: CallStates.DONE, + }, + { + id: 'story--id [6] waitFor [1] stringMatching', + parentId: 'story--id [6] waitFor', + storyId: 'story--id', + cursor: 2, + path: ['expect'], + method: 'stringMatching', + args: [{ __regexp__: { flags: 'gi', source: '([A-Z])w+' } }], + interceptable: false, + retain: false, + status: CallStates.DONE, + }, + { + id: 'story--id [6] waitFor [2] toHaveBeenCalledWith', + parentId: 'story--id [6] waitFor', + storyId: 'story--id', + cursor: 3, + path: [{ __callId__: 'story--id [6] waitFor [0] expect' }], + method: 'toHaveBeenCalledWith', + args: [{ __callId__: 'story--id [6] waitFor [1] stringMatching', retain: false }], + interceptable: true, + retain: false, + status: CallStates.DONE, + }, + { + id: 'story--id [7] expect', + storyId: 'story--id', + cursor: 7, + path: [], + method: 'expect', + args: [{ __function__: { name: 'handleReset' } }], + interceptable: false, + retain: false, + status: CallStates.DONE, + }, + { + id: 'story--id [8] toHaveBeenCalled', + storyId: 'story--id', + cursor: 8, + path: [{ __callId__: 'story--id [7] expect' }, 'not'], + method: 'toHaveBeenCalled', + args: [], + interceptable: true, + retain: false, + status: finalStatus, + }, + ]; - const overrides = CallStates.ERROR - ? { exception: { name: 'Error', stack: '', message: "Things didn't work!" } } - : {}; + if (finalStatus === CallStates.ERROR) { + calls[calls.length - 1].exception = { + name: 'Error', + stack: '', + message: 'Oops!', + callId: calls[calls.length - 1].id, + }; + } - return { ...defaultData, ...overrides }; + return calls; }; + +export const getInteractions = (finalStatus: CallStates) => + getCalls(finalStatus).filter((call) => call.interceptable); diff --git a/app/angular/src/client/preview/angular-beta/StorybookModule.ts b/app/angular/src/client/preview/angular-beta/StorybookModule.ts index 68c443375a83..275b490c18bc 100644 --- a/app/angular/src/client/preview/angular-beta/StorybookModule.ts +++ b/app/angular/src/client/preview/angular-beta/StorybookModule.ts @@ -7,7 +7,7 @@ import deprecate from 'util-deprecate'; import { ICollection, StoryFnAngularReturnType } from '../types'; import { storyPropsProvider } from './StorybookProvider'; import { isComponentAlreadyDeclaredInModules } from './utils/NgModulesAnalyzer'; -import { isDeclarable } from './utils/NgComponentAnalyzer'; +import { isDeclarable, isStandaloneComponent } from './utils/NgComponentAnalyzer'; import { createStorybookWrapperComponent } from './StorybookWrapperComponent'; import { computesTemplateFromComponent } from './ComputesTemplateFromComponent'; @@ -61,6 +61,7 @@ export const getStorybookModuleMetadata = ( props ); + const isStandalone = isStandaloneComponent(component); // Look recursively (deep) if the component is not already declared by an import module const requiresComponentDeclaration = isDeclarable(component) && @@ -68,7 +69,8 @@ export const getStorybookModuleMetadata = ( component, moduleMetadata.declarations, moduleMetadata.imports - ); + ) && + !isStandalone; return { declarations: [ @@ -76,7 +78,11 @@ export const getStorybookModuleMetadata = ( ComponentToInject, ...(moduleMetadata.declarations ?? []), ], - imports: [BrowserModule, ...(moduleMetadata.imports ?? [])], + imports: [ + BrowserModule, + ...(isStandalone ? [component] : []), + ...(moduleMetadata.imports ?? []), + ], providers: [storyPropsProvider(storyProps$), ...(moduleMetadata.providers ?? [])], entryComponents: [...(moduleMetadata.entryComponents ?? [])], schemas: [...(moduleMetadata.schemas ?? [])], diff --git a/app/angular/src/client/preview/angular-beta/utils/NgComponentAnalyzer.test.ts b/app/angular/src/client/preview/angular-beta/utils/NgComponentAnalyzer.test.ts index 03eba18a7236..faa7cdce09ff 100644 --- a/app/angular/src/client/preview/angular-beta/utils/NgComponentAnalyzer.test.ts +++ b/app/angular/src/client/preview/angular-beta/utils/NgComponentAnalyzer.test.ts @@ -19,6 +19,7 @@ import { isComponent, isDeclarable, getComponentDecoratorMetadata, + isStandaloneComponent, } from './NgComponentAnalyzer'; describe('getComponentInputsOutputs', () => { @@ -235,6 +236,46 @@ describe('isComponent', () => { }); }); +describe('isStandaloneComponent', () => { + it('should return true with a Component with "standalone: true"', () => { + // TODO: `standalone` is only available in Angular v14. Remove cast to `any` once + // Angular deps are updated to v14.x.x. + @Component({ standalone: true } as any) + class FooComponent {} + + expect(isStandaloneComponent(FooComponent)).toEqual(true); + }); + + it('should return false with a Component with "standalone: false"', () => { + // TODO: `standalone` is only available in Angular v14. Remove cast to `any` once + // Angular deps are updated to v14.x.x. + @Component({ standalone: false } as any) + class FooComponent {} + + expect(isStandaloneComponent(FooComponent)).toEqual(false); + }); + + it('should return false with a Component without the "standalone" property', () => { + @Component({}) + class FooComponent {} + + expect(isStandaloneComponent(FooComponent)).toEqual(false); + }); + + it('should return false with simple class', () => { + class FooPipe {} + + expect(isStandaloneComponent(FooPipe)).toEqual(false); + }); + + it('should return false with Directive', () => { + @Directive() + class FooDirective {} + + expect(isStandaloneComponent(FooDirective)).toEqual(false); + }); +}); + describe('getComponentDecoratorMetadata', () => { it('should return Component with a Component', () => { @Component({ selector: 'foo' }) diff --git a/app/angular/src/client/preview/angular-beta/utils/NgComponentAnalyzer.ts b/app/angular/src/client/preview/angular-beta/utils/NgComponentAnalyzer.ts index ae88972dfe26..36bd036631e3 100644 --- a/app/angular/src/client/preview/angular-beta/utils/NgComponentAnalyzer.ts +++ b/app/angular/src/client/preview/angular-beta/utils/NgComponentAnalyzer.ts @@ -108,6 +108,18 @@ export const isComponent = (component: any): component is Type => { return (decorators || []).some((d) => d instanceof Component); }; +export const isStandaloneComponent = (component: any): component is Type => { + if (!component) { + return false; + } + + const decorators = reflectionCapabilities.annotations(component); + + // TODO: `standalone` is only available in Angular v14. Remove cast to `any` once + // Angular deps are updated to v14.x.x. + return (decorators || []).some((d) => d instanceof Component && (d as any).standalone); +}; + /** * Returns all component decorator properties * is used to get all `@Input` and `@Output` Decorator diff --git a/app/react/src/client/preview/render.tsx b/app/react/src/client/preview/render.tsx index 94db184a3b6b..e2f305158a58 100644 --- a/app/react/src/client/preview/render.tsx +++ b/app/react/src/client/preview/render.tsx @@ -147,4 +147,6 @@ export async function renderToDOM( } await renderElement(element, domElement); + + return () => unmountElement(domElement); } diff --git a/app/vue/src/client/preview/config.ts b/app/vue/src/client/preview/config.ts index 036f51eba182..759c77b9abeb 100644 --- a/app/vue/src/client/preview/config.ts +++ b/app/vue/src/client/preview/config.ts @@ -1,4 +1,4 @@ export { render, renderToDOM } from './render'; -export { decorateStory } from './decorateStory'; +export { decorateStory as applyDecorators } from './decorateStory'; export const parameters = { framework: 'vue' }; diff --git a/app/vue3/src/client/preview/config.ts b/app/vue3/src/client/preview/config.ts index 69f6b3b8683e..589efca6a13f 100644 --- a/app/vue3/src/client/preview/config.ts +++ b/app/vue3/src/client/preview/config.ts @@ -1,4 +1,4 @@ export { render, renderToDOM } from './render'; -export { decorateStory } from './decorateStory'; +export { decorateStory as applyDecorators } from './decorateStory'; export const parameters = { framework: 'vue3' }; diff --git a/docs/addons/writing-addons.md b/docs/addons/writing-addons.md index 7b3079ad94a0..071ac289e240 100644 --- a/docs/addons/writing-addons.md +++ b/docs/addons/writing-addons.md @@ -50,13 +50,22 @@ Once you've gone through the prompts, your `package.json` should look like: ### Build system -We'll need to add the necessary dependencies and make some adjustments. Run the following commands: +We'll need to add the necessary dependencies and make some adjustments. Run the following command to install the required dependencies: -```shell -# Installs React and Babel CLI -yarn add react react-dom @babel/cli + -# Adds Storybook: + + + + +Initialize a local Storybook instance to allow you to test your addon. + +```shell npx sb init ``` @@ -246,4 +255,4 @@ To dive deeper, we recommend Storybook's [creating an addon](https://storybook.j ### Addon kit -To help you jumpstart the addon development, the Storybook maintainers created an [`addon-kit`](https://github.com/storybookjs/addon-kit), use it to bootstrap your next addon. \ No newline at end of file +To help you jumpstart the addon development, the Storybook maintainers created an [`addon-kit`](https://github.com/storybookjs/addon-kit), use it to bootstrap your next addon. diff --git a/docs/api/cli-options.md b/docs/api/cli-options.md index ae567dd69631..6ca92991ce99 100644 --- a/docs/api/cli-options.md +++ b/docs/api/cli-options.md @@ -5,7 +5,9 @@ title: 'CLI options' Storybook comes with two CLI utilities: `start-storybook` and `build-storybook`.
+ Storybook collects completely anonymous data to help us improve user experience. Participation is optional, and you may [opt-out](../configure/telemetry.md#how-to-opt-out) if you'd not like to share any information. +
Pass these commands the following options to alter Storybook's behavior. diff --git a/docs/builders/webpack.md b/docs/builders/webpack.md index a2571d22ea0c..fa5568bb6c52 100644 --- a/docs/builders/webpack.md +++ b/docs/builders/webpack.md @@ -40,16 +40,34 @@ You can import `.json` files and have them expanded to a JavaScript object: -If you want to know the exact details of the Webpack config, the best way is to run either of the following: +If you want to know the exact details of the Webpack config, the best way is to run either of the following commands: -```shell +For development mode: -## Development mode -yarn start-storybook --debug-webpack + + + + + + +For production mode: -## Production mode -yarn build-storybook --debug-webpack -``` + + + + + + ### Code splitting @@ -193,11 +211,11 @@ When working with TypeScript projects, the default Webpack configuration may fai
-💡 Learn more about Storybook's built-in TypeScript support or see this issue for more information. +💡 Learn more about Storybook's built-in TypeScript support or see this issue for more information.
#### Learn more about builders - [Vite builder](./vite.md) for bundling with Vite -- [Webpack builder](./webpack.md) for bundling with Webpack -- [Builder API](./builder-api.md) for building a Storybook builder \ No newline at end of file +- Webpack builder for bundling with Webpack +- [Builder API](./builder-api.md) for building a Storybook builder diff --git a/docs/configure/css-troubleshooting/angular.mdx b/docs/configure/css-troubleshooting/angular.mdx index ab6674b7547e..d9c6c7a81dd2 100644 --- a/docs/configure/css-troubleshooting/angular.mdx +++ b/docs/configure/css-troubleshooting/angular.mdx @@ -42,7 +42,11 @@ Additionally, if you need Storybook specific styles that are separate from your ``` ### Nx with Angular 13 -If you're working with Storybook and [NX libraries](https://nx.dev/structure/library-types), you can extend your project's configuration (i.e., `project.json`) and provide the application's styles. For example: + +If you're working with Storybook and [Nx libraries](https://nx.dev/structure/library-types), +you can extend your project's configuration (i.e., `project.json`) and provide the application's styles. + +For earlier Nx versions (prior to `14.1.8`), your configuration would look like this: ```json "build-storybook": { @@ -56,11 +60,35 @@ If you're working with Storybook and [NX libraries](https://nx.dev/structure/lib }, "projectBuildConfig": "example-lib:build-storybook", "styles": ["apps/example-app/src/styles.scss"] + } + } +``` + +Starting with version `14.1.8`, Nx uses the Storybook builder directly, which means any configuration supplied to the builder also applies to the NX setup. If you're working with a library, you'll need to configure the styling options ( e.g., preprocessors) inside the `build-storybook` `options` configuration object. For example: + +```json + "storybook": { + "executor": "@storybook/angular:start-storybook", + "options": { + "configDir": "apps/example-lib/.storybook", + "browserTarget": "example-lib:build-storybook", + }, }, - "configurations": { - "ci": { - "quiet": true + "build-storybook": { + "executor": "@storybook/angular:build-storybook", + "outputs": ["{options.outputPath}"], + "options": { + "outputDir": "dist/storybook/example-lib", + "configDir": "apps/example-lib/.storybook", + "browserTarget": "example-lib:build-storybook", + "styles": [".storybook/custom-styles.scss"], + "stylePreprocessorOptions": { + "includePaths": [ + "libs/design-system/src/lib" + ] + } } } - } ``` + +When Nx runs, it will load Storybook's configuration and styling based on the `storybook`'s [`browserTarget`](https://nx.dev/storybook/extra-topics-for-angular-projects#setting-up-browsertarget). diff --git a/docs/configure/environment-variables.md b/docs/configure/environment-variables.md index d6439226bb4d..1109db35c15b 100644 --- a/docs/configure/environment-variables.md +++ b/docs/configure/environment-variables.md @@ -9,6 +9,12 @@ If you supply an environment variable prefixed with `STORYBOOK_`, it will be ava STORYBOOK_THEME=red STORYBOOK_DATA_KEY=12345 npm run storybook ``` +
+ + 💡 Do not store any secrets (e.g., private API keys) or other types of sensitive information in your Storybook. Environment variables are embedded into the build, meaning anyone can view them by inspecting your files. + +
+ Then we can access these environment variables anywhere inside our preview JavaScript code like below: diff --git a/docs/configure/overview.md b/docs/configure/overview.md index 83eed8505c43..5cc0081afff2 100644 --- a/docs/configure/overview.md +++ b/docs/configure/overview.md @@ -28,7 +28,7 @@ The `main.js` configuration file is a [preset](../addons/addon-types.md) and, as - `stories` - an array of globs that indicates the [location of your story files](#configure-story-loading), relative to `main.js`. - `addons` - a list of the [addons](https://storybook.js.org/addons/) you are using. -- `webpackFinal` - custom [webpack configuration](./webpack.md#extending-storybooks-webpack-config). +- `webpackFinal` - custom [webpack configuration](../builders/webpack.md#extending-storybooks-webpack-config). - `babel` - custom [babel configuration](./babel.md). - `framework` - framework specific configurations to help the loading and building process. @@ -178,14 +178,15 @@ You can also use Storybook's API to configure your project with TypeScript. Unde | --------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `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
`staticDirs:['../public']` | -| `addons` | Sets the list of [addons](https://storybook.js.org/addons/) loaded by Storybook
`addons:['@storybook/addon-essentials']` | +| `addons` | Sets the list of [addons](https://storybook.js.org/addons/) loaded by Storybook
`addons:['@storybook/addon-essentials']` | | `typescript` | Configures how Storybook handles [TypeScript files](./typescript.md)
`typescript: { check: false, checkOptions: {} }` | | `framework` | Configures Storybook based on a set of framework-specific settings
`framework:'@storybook/svelte'` | | `core` | Configures Storybook's internal features.
`core: { builder: 'webpack5' }` | | `features` | Enables Storybook's additional features.
See table below for a list of available features `features: { storyStoreV7: true }` | | `refs` | Configures [Storybook composition](../sharing/storybook-composition.md)
`refs:{ example: { title: 'ExampleStorybook', url:'https://your-url.com' } }` | | `logLevel` | Configures Storybook's logs in the browser terminal. Useful for debugging
`logLevel: 'debug'` | -| `webpackFinal` | Customize Storybook's [Webpack](./webpack.md) setup
`webpackFinal: async (config:any) => { return config; }` | +| `webpackFinal` | Customize Storybook's [Webpack](../builders/webpack.md) setup
`webpackFinal: async (config:any) => { return config; }` | +| `env` | Defines custom Storybook [environment variables](./environment-variables.md#using-storybook-configuration).
`env: (config) => ({...config, EXAMPLE_VAR: 'Example var' }),` | ## Configure story rendering diff --git a/docs/configure/story-rendering.md b/docs/configure/story-rendering.md index 360dde244f14..f930fe1e3765 100644 --- a/docs/configure/story-rendering.md +++ b/docs/configure/story-rendering.md @@ -2,7 +2,7 @@ title: 'Story rendering' --- -In Storybook, your stories render in a particular “preview” iframe (Canvas tab) inside the larger Storybook web application. The JavaScript build configuration of the preview is controlled by a [webpack](./webpack.md) config, but you also may want to directly control the rendered HTML to help your stories render correctly. +In Storybook, your stories render in a particular “preview” iframe (Canvas tab) inside the larger Storybook web application. The JavaScript build configuration of the preview is controlled by a [webpack](../builders/webpack.md) config, but you also may want to directly control the rendered HTML to help your stories render correctly. ## Adding to <head> diff --git a/docs/configure/styling-and-css.md b/docs/configure/styling-and-css.md index 2253874499fb..a6c01a6589bf 100644 --- a/docs/configure/styling-and-css.md +++ b/docs/configure/styling-and-css.md @@ -10,7 +10,7 @@ CSS-in-JS libraries are designed to use basic JavaScript, and they often work in ### Importing CSS files -If your component files import their CSS, Storybook's webpack configuration will work out of the box. The noticeable exception to this is if you're using a CSS precompiler. In this case, you can either install and configure a Storybook preset (e.g., [SCSS preset](https://github.com/storybookjs/presets/tree/master/packages/preset-scss)), or customize [Storybook's webpack configuration](./webpack.md#extending-storybooks-webpack-config) and include the appropriate loader. +If your component files import their CSS, Storybook's webpack configuration will work out of the box. The noticeable exception to this is if you're using a CSS precompiler. In this case, you can either install and configure a Storybook preset (e.g., [SCSS preset](https://github.com/storybookjs/presets/tree/master/packages/preset-scss)), or customize [Storybook's webpack configuration](../builders/webpack.md#extending-storybooks-webpack-config) and include the appropriate loader. @@ -18,4 +18,4 @@ To use your CSS in all stories, you import it in [`.storybook/preview.js`](./ove ### Adding webfonts -If you need webfonts to be available, you may need to add some code to the [`.storybook/preview-head.html`](./story-rendering.md#adding-to-head) file. We recommend including any assets with your Storybook if possible, in which case you likely want to configure the [static file location](./images-and-assets.md#serving-static-files-via-storybook-configuration). \ No newline at end of file +If you need webfonts to be available, you may need to add some code to the [`.storybook/preview-head.html`](./story-rendering.md#adding-to-head) file. We recommend including any assets with your Storybook if possible, in which case you likely want to configure the [static file location](./images-and-assets.md#serving-static-files-via-storybook-configuration). diff --git a/docs/contribute/code.md b/docs/contribute/code.md index 9a1f4fada5b6..8b55caa63fe4 100644 --- a/docs/contribute/code.md +++ b/docs/contribute/code.md @@ -6,18 +6,21 @@ Contribute a new feature or bug fix to [Storybook's monorepo](https://github.com ## Initial setup -First [fork](https://docs.github.com/en/github/getting-started-with-github/quickstart/fork-a-repo) the Storybook repository then clone and build your fork locally. Run the following commands: +Start by [forking](https://docs.github.com/en/github/getting-started-with-github/quickstart/fork-a-repo) the Storybook monorepo and cloning it locally. ```shell git clone https://github.com/your-username/storybook.git -cd storybook -yarn -yarn bootstrap --core +``` + +Navigate to the `storybook` directory and install the required dependencies with the following commands: + +```shell +yarn && yarn bootstrap --core ``` ## Run tests & examples -Once you've completed the [initial setup](#run-tests-&-examples), you should have a fully functional version of Storybook built on your local machine. Before making any code changes, it's helpful to verify that everything is working as it should. More specifically, the test suite and examples. +Once you've completed the [initial setup](#initial-setup), you should have a fully functional version of Storybook built on your local machine. Before making any code changes, it's helpful to verify that everything is working as it should. More specifically, the test suite and examples. Run the following command to execute the tests: @@ -28,8 +31,7 @@ yarn test Once the tests finish, check if the examples are working with the following commands: ```shell -cd examples/cra-ts-essentials -yarn storybook +cd examples/cra-ts-essentials && yarn storybook ```
@@ -106,7 +108,7 @@ Storybook's monorepo is set up to rely on end-to-end testing with [Cypress](http Before submitting your contribution, run the test suite one last time with: -```sh +```shell yarn test ``` @@ -133,7 +135,7 @@ We encourage bug reports to include reproductions. In the same way that it's pos To do so, run the following command in the root of the monorepo: -```sh +```shell npx sb@next link https://github.com/your-username/your-project.git ``` @@ -141,7 +143,7 @@ This command creates a project `../storybook-repros/your-project`, and automatic If you already have a reproduction on your local machine, you can similarly link it to your monorepo dev setup with the `--local` flag: -```sh +```shell npx sb@next link --local /path/to/local-repro-directory ``` diff --git a/docs/contribute/new-snippets.md b/docs/contribute/new-snippets.md index 84e4a91439b2..35a88ea36834 100644 --- a/docs/contribute/new-snippets.md +++ b/docs/contribute/new-snippets.md @@ -89,11 +89,15 @@ Go through the rest of the documentation and repeat the process. Before submitting your contribution, we advise you to check your work against the Storybook website. Doing this prevents last-minute issues with the documentation and is also an excellent way for the maintainers to merge faster once you submit the pull request. However, failing to do so will lead one of the maintainers to notify you that your contribution has an issue. -Start by forking [frontpage repo](https://github.com/storybookjs/frontpage). Then, clone and install the dependencies with the following commands: +Start by forking [frontpage repo](https://github.com/storybookjs/frontpage) and cloning it locally. ```shell git clone https://github.com/your-username/frontpage.git -cd frontpage +``` + +Navigate to the `frontpage` directory and install the required dependencies with the following command: + +```shell yarn ``` diff --git a/docs/essentials/interactions.md b/docs/essentials/interactions.md index 4e1ca5099177..a46bcc13b11a 100644 --- a/docs/essentials/interactions.md +++ b/docs/essentials/interactions.md @@ -18,13 +18,16 @@ The interactions are written using a Storybook-instrumented version of [Testing Since Interactions is still experimental, it doesn't yet ship with Storybook by default. As such, you'll have to install it. You may also want to add our wrappers for Testing Library and Jest. -```shell -# With npm -npm install @storybook/addon-interactions @storybook/jest @storybook/testing-library --save-dev + -# With yarn -yarn add --dev @storybook/addon-interactions @storybook/jest @storybook/testing-library -``` + + + Next, update [`.storybook/main.js`](../configure/overview.md#configure-story-rendering) to the following: diff --git a/docs/essentials/introduction.md b/docs/essentials/introduction.md index ea508ccb5411..bd2b6661e24d 100644 --- a/docs/essentials/introduction.md +++ b/docs/essentials/introduction.md @@ -18,13 +18,16 @@ If you ran `sb init` to include Storybook in your project, the Essentials addon If you're upgrading from a previous Storybook version, you'll need to run the following command in your terminal: -```shell -#With npm -npm install -D @storybook/addon-essentials + -#With yarn -yarn add -D @storybook/addon-essentials -``` + + + Update your Storybook configuration (in [`.storybook/main.js`](../configure/overview.md#configure-story-rendering)) to include the Essentials addon. @@ -44,14 +47,16 @@ Essentials is "zero-config”. It comes with a recommended configuration out of If you need to reconfigure any of the [individual Essentials addons](https://storybook.js.org/addons/tag/essentials), install them manually by following the installation instructions, register them in your Storybook configuration file (i.e., [`.storybook/main.js`](../configure/overview.md#configure-story-rendering)) and adjust the configuration to suit your needs. For example: -```shell -#With npm -npm install -D @storybook/addon-actions + + -#With yarn -yarn add -D @storybook/addon-actions -``` + diff --git a/docs/faq.md b/docs/faq.md index a76ebab17e5b..cc1dec1ca45a 100644 --- a/docs/faq.md +++ b/docs/faq.md @@ -145,72 +145,70 @@ With the release of version 6.0, we updated our documentation as well. That does We're only covering versions 5.3 and 5.0 as they were important milestones for Storybook. If you want to go back in time a little more, you'll have to check the specific release in the monorepo. - -| Section | Page | Current Location | Version 5.3 location | Version 5.0 location | -|------------------|-------------------------------------------|-----------------------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------| -| Get started | Install | [See current documentation](./get-started/install.md) | [See versioned documentation](https://github.com/storybookjs/storybook/tree/release/5.3/docs/src/pages/guides/quick-start-guide) | [See versioned documentation](https://github.com/storybookjs/storybook/tree/release/5.0/docs/src/pages/guides/quick-start-guide) | -| | What's a story | [See current documentation](./get-started/whats-a-story.md) | [See versioned documentation for your framework](https://github.com/storybookjs/storybook/tree/release/5.3/docs/src/pages/guides) | [See versioned documentation for your framework](https://github.com/storybookjs/storybook/tree/release/5.0/docs/src/pages/guides) | -| | Browse Stories | [See current documentation](./get-started/browse-stories.md) | [See versioned documentation for your framework](https://github.com/storybookjs/storybook/tree/release/5.3/docs/src/pages/guides) | [See versioned documentation for your framework](https://github.com/storybookjs/storybook/blob/release/5.0/docs/src/pages/guides) | -| | Setup | [See current documentation](./get-started/setup.md) | [See versioned documentation for your framework](https://github.com/storybookjs/storybook/tree/release/5.3/docs/src/pages/guides) | [See versioned documentation for your framework](https://github.com/storybookjs/storybook/tree/release/5.0/docs/src/pages/guides) | -| Write stories | Introduction | [See current documentation](./writing-stories/introduction.md) | [See versioned documentation](https://github.com/storybookjs/storybook/tree/release/5.3/docs/src/pages/basics/writing-stories) | [See versioned documentation](https://github.com/storybookjs/storybook/tree/release/5.0/docs/src/pages/basics/writing-stories) | -| | Parameters | [See current documentation](./writing-stories/parameters.md) | [See versioned documentation](https://github.com/storybookjs/storybook/tree/release/5.3/docs/src/pages/basics/writing-stories/index.md#parameters) | Non existing feature or undocumented | -| | Decorators | [See current documentation](./writing-stories/decorators.md) | [See versioned documentation](https://github.com/storybookjs/storybook/tree/release/5.3/docs/src/pages/basics/writing-stories/index.md#decorators) | [See versioned documentation](https://github.com/storybookjs/storybook/tree/release/5.0/docs/src/pages/basics/writing-stories/index.md#using-decorators) | -| | Naming components and hierarchy | [See current documentation](./writing-stories/naming-components-and-hierarchy.md) | [See versioned documentation](https://github.com/storybookjs/storybook/tree/release/5.3/docs/src/pages/basics/writing-stories) | [See versioned documentation](https://github.com/storybookjs/storybook/tree/release/5.0/docs/src/pages/basics/writing-stories) | -| | Build pages and screens | [See current documentation](./writing-stories/build-pages-with-storybook.md) | Non existing feature or undocumented | Non existing feature or undocumented | -| | Stories for multiple components | [See current documentation](./writing-stories/stories-for-multiple-components.md) | Non existing feature or undocumented | Non existing feature or undocumented | -| Write docs | DocsPage | [See current documentation](./writing-docs/docs-page.md) | See versioned addon documentation | Non existing feature or undocumented | -| | MDX | [See current documentation](./writing-docs/mdx.md) | See versioned addon documentation | Non existing feature or undocumented | -| | Doc Blocks/Argstable | [See current documentation](./writing-docs/doc-block-argstable.md) | [See versioned addon documentation](https://github.com/storybookjs/storybook/tree/release/5.3/addons/docs/) | Non existing feature or undocumented | -| | Doc Blocks/Canvas | [See current documentation](./writing-docs/doc-block-canvas.md) | [See versioned addon documentation](https://github.com/storybookjs/storybook/tree/release/5.3/addons/docs/) | Non existing feature or undocumented | -| | Doc Blocks/Color Palette | [See current documentation](./writing-docs/doc-block-colorpalette.md) | [See versioned addon documentation](https://github.com/storybookjs/storybook/tree/release/5.3/addons/docs/) | Non existing feature or undocumented | -| | Doc Blocks/Description | [See current documentation](./writing-docs/doc-block-description.md) | [See versioned addon documentation](https://github.com/storybookjs/storybook/tree/release/5.3/addons/docs/) | Non existing feature or undocumented | -| | Doc Blocks/Icon Gallery | [See current documentation](./writing-docs/doc-block-icongallery.md) | [See versioned addon documentation](https://github.com/storybookjs/storybook/tree/release/5.3/addons/docs/) | Non existing feature or undocumented | -| | Doc Blocks/Source | [See current documentation](./writing-docs/doc-block-source.md) | [See versioned addon documentation](https://github.com/storybookjs/storybook/tree/release/5.3/addons/docs/) | Non existing feature or undocumented | -| | Doc Blocks/Story | [See current documentation](./writing-docs/doc-block-story.md) | [See versioned addon documentation](https://github.com/storybookjs/storybook/tree/release/5.3/addons/docs/) | Non existing feature or undocumented | -| | Doc Blocks/Typeset | [See current documentation](./writing-docs/doc-block-typeset.md) | [See versioned addon documentation](https://github.com/storybookjs/storybook/tree/release/5.3/addons/docs/) | Non existing feature or undocumented | -| | Preview and build docs | [See current documentation](./writing-docs/build-documentation.md) | Non existing feature or undocumented | Non existing feature or undocumented | -| Testing | Visual tests | [See current documentation](./writing-tests/visual-testing.md) | [See versioned documentation](https://github.com/storybookjs/storybook/tree/release/5.3/docs/src/pages/testing/automated-visual-testing) | [See versioned documentation](https://github.com/storybookjs/storybook/tree/release/5.0/docs/src/pages/testing/automated-visual-testing) | -| | Accessibility tests | [See current documentation](./writing-tests/accessibility-testing.md) | Non existing feature or undocumented | Non existing feature or undocumented | -| | Interaction tests | [See current documentation](./writing-tests/interaction-testing.md) | [See versioned documentation](https://github.com/storybookjs/storybook/tree/release/5.3/docs/src/pages/testing/interaction-testing) | [See versioned documentation](https://github.com/storybookjs/storybook/tree/release/5.0/docs/src/pages/testing/interaction-testing) | -| | Snapshot tests | [See current documentation](./writing-tests/snapshot-testing.md) | [See versioned documentation](https://github.com/storybookjs/storybook/tree/release/5.3/docs/src/pages/testing/structural-testing) | [See versioned documentation](https://github.com/storybookjs/storybook/tree/release/5.0/docs/src/pages/testing/structural-testing) | -| | Import stories in tests | [See current documentation](./writing-tests/importing-stories-in-tests.md) | [See versioned documentation](https://github.com/storybookjs/storybook/tree/release/5.3/docs/src/pages/testing/react-ui-testing) | [See versioned documentation](https://github.com/storybookjs/storybook/tree/release/5.0/docs/src/pages/testing/react-ui-testing) | -| Sharing | Publish Storybook | [See current documentation](./sharing/publish-storybook.md) | [See versioned documentation](https://github.com/storybookjs/storybook/tree/release/5.3/docs/src/pages/basics/exporting-storybook) | [See versioned documentation](https://github.com/storybookjs/storybook/tree/release/5.0/docs/src/pages/basics/exporting-storybook) | -| | Embed | [See current documentation](./sharing/embed.md) | Non existing feature or undocumented | Non existing feature or undocumented | -| | Composition | [See current documentation](./sharing/storybook-composition.md) | Non existing feature or undocumented | Non existing feature or undocumented | -| | Package Composition | [See current documentation](./sharing/package-composition.md) | Non existing feature or undocumented | Non existing feature or undocumented | -| Essential addons | Controls | [See current documentation](./essentials/controls.md) | Controls are specific to version 6.0 see [Knobs versioned documentation](https://github.com/storybookjs/storybook/tree/release/5.3/addons/knobs) | Controls are specific to version 6.0 see [Knobs versioned documentation](https://github.com/storybookjs/storybook/tree/release/5.0/addons/knobs) | -| | Actions | [See current documentation](./essentials/actions.md) | [See addon versioned documentation](https://github.com/storybookjs/storybook/tree/release/5.3/addons/actions) | [See addon versioned documentation](https://github.com/storybookjs/storybook/tree/release/5.0/addons/actions) | -| | Viewport | [See current documentation](./essentials/viewport.md) | [See addon versioned documentation](https://github.com/storybookjs/storybook/tree/release/5.3/addons/viewport) | [See addon versioned documentation](https://github.com/storybookjs/storybook/tree/release/5.0/addons/viewport) | -| | Backgrounds | [See current documentation](./essentials/backgrounds.md) | [See addon versioned documentation](https://github.com/storybookjs/storybook/tree/release/5.3/addons/backgrounds) | [See addon versioned documentation](https://github.com/storybookjs/storybook/tree/release/5.0/addons/backgrounds) | -| | Toolbars and globals | [See current documentation](./essentials/toolbars-and-globals.md) | [See versioned documentation](https://github.com/storybookjs/storybook/tree/release/5.3/docs/src/pages/basics/toolbar-guide) | Non existing feature or undocumented | -| Configure | Overview | [See current documentation](./configure/overview.md) | [See versioned documentation](https://github.com/storybookjs/storybook/tree/release/5.3/docs/src/pages/configurations/overview) | [See versioned documentation](https://github.com/storybookjs/storybook/tree/release/5.0/docs/src/pages/basics/writing-stories) | -| | Integration/Babel | [See current documentation](./configure/babel.md) | See versioned documentation here and [here](https://github.com/storybookjs/storybook/tree/release/5.3/docs/src/pages/configurations/custom-babel-config) | See versioned documentation here and [here](https://github.com/storybookjs/storybook/tree/release/5.0/docs/src/pages/configurations/custom-babel-config) | -| | Integration/Typescript | [See current documentation](./configure/typescript.md) | [See versioned documentation](https://github.com/storybookjs/storybook/tree/release/5.3/docs/src/pages/configurations/typescript-config) | [See versioned documentation](https://github.com/storybookjs/storybook/tree/release/5.0/docs/src/pages/configurations/typescript-config) | -| | Integration/Styling and CSS | [See current documentation](./configure/styling-and-css.md) | See versioned documentation | See versioned documentation | -| | Integration/Images and assets | [See current documentation](./configure/images-and-assets.md) | See versioned documentation | See versioned documentation | -| | Story rendering | [See current documentation](./configure/story-rendering.md) | See versioned documentation [here](https://github.com/storybookjs/storybook/tree/release/5.3/docs/src/pages/configurations/add-custom-head-tags) and [here](https://github.com/storybookjs/storybook/tree/release/5.3/docs/src/pages/configurations/add-custom-body) | See versioned documentation [here](https://github.com/storybookjs/storybook/tree/release/5.0/docs/src/pages/configurations/add-custom-head-tags) | -| | Story Layout | [See current documentation](./configure/story-layout.md) | Non existing feature or undocumented | Non existing feature or undocumented | -| | User Interface/Features and behavior | [See current documentation](./configure/features-and-behavior.md) | [See versioned documentation](https://github.com/storybookjs/storybook/tree/release/5.3/docs/src/pages/configurations/options-parameter) | [See versioned documentation](https://github.com/storybookjs/storybook/tree/release/5.0/docs/src/pages/configurations/options-parameter) | -| | User Interface/Theming | [See current documentation](./configure/theming.md) | [See versioned documentation](https://github.com/storybookjs/storybook/tree/release/5.3/docs/src/pages/configurations/theming) | [See versioned documentation](https://github.com/storybookjs/storybook/tree/release/5.0/docs/src/pages/configurations/theming) | -| | User Interface/Sidebar & URLS | [See current documentation](./configure/sidebar-and-urls.md) | [See versioned documentation](https://github.com/storybookjs/storybook/tree/release/5.3/docs/src/pages/configurations/options-parameter) | [See versioned documentation](https://github.com/storybookjs/storybook/tree/release/5.0/docs/src/pages/configurations/options-parameter) | -| | Environment variables | [See current documentation](./configure/environment-variables.md) | [See versioned documentation](https://github.com/storybookjs/storybook/tree/release/5.3/docs/src/pages/configurations/env-vars) | [See versioned documentation](https://github.com/storybookjs/storybook/tree/release/5.0/docs/src/pages/configurations/env-vars) | -| Builders | Introduction | [See current documentation](./builders/overview.md) | Non existing feature or undocumented | Non existing feature or undocumented | -| | Vite | [See current documentation](./builders/vite.md) | Non existing feature or undocumented | Non existing feature or undocumented | -| | Webpack | [See current documentation](./builders/webpack.md) | [See versioned documentation](https://github.com/storybookjs/storybook/tree/release/5.3/docs/src/pages/configurations/custom-webpack-config/index.md) | [See versioned documentation](https://github.com/storybookjs/storybook/tree/release/5.0/docs/src/pages/configurations/custom-webpack-config/index.md) | -| | Builder API | [See current documentation](./builders/builder-api.md) | Non existing feature or undocumented | Non existing feature or undocumented | -| Addons | Introduction | [See current documentation](./addons/introduction.md) | [See versioned documentation](https://github.com/storybookjs/storybook/tree/release/5.3/docs/src/pages/addons/writing-addons) | [See versioned documentation](https://github.com/storybookjs/storybook/tree/release/5.0/docs/src/pages/addons/writing-addons) | -| | Install addons | [See current documentation](./addons/install-addons.md) | [See versioned documentation](https://github.com/storybookjs/storybook/tree/release/5.3/docs/src/pages/addons/using-addons/) | [See versioned documentation](https://github.com/storybookjs/storybook/tree/release/5.0/docs/src/pages/addons/using-addons/) | -| | Writing Addons | [See current documentation](./addons/writing-addons.md) | [See versioned documentation](https://github.com/storybookjs/storybook/tree/release/5.3/docs/src/pages/addons/writing-addons) | [See versioned documentation](https://github.com/storybookjs/storybook/tree/release/5.0/docs/src/pages/addons/writing-addons) | -| | Writing Presets | [See current documentation](./addons/writing-presets.md) | [See versioned documentation](https://github.com/storybookjs/storybook/tree/release/5.3/docs/src/pages/presets/writing-presets) | Non existing feature or undocumented | -| | Addons Knowledge Base | [See current documentation](./addons/addon-knowledge-base.md) | [See versioned documentation](https://github.com/storybookjs/storybook/tree/release/5.3/docs/src/pages/addons/writing-addons) | [See versioned documentation](https://github.com/storybookjs/storybook/tree/release/5.0/docs/src/pages/addons/writing-addons) | -| | Types of addons | [See current documentation](./addons/addon-types.md) | Non existing feature or undocumented | Non existing feature or undocumented | -| | Addons API | [See current documentation](./addons/addons-api.md) | [See versioned documentation](https://github.com/storybookjs/storybook/tree/release/5.3/docs/src/pages/addons/api) | [See versioned documentation](https://github.com/storybookjs/storybook/tree/release/5.0/docs/src/pages/addons/api) | -| API | Stories/Component Story Format | [See current documentation](./api/csf.md) | [See versioned documentation](https://github.com/storybookjs/storybook/tree/release/5.3/docs/src/pages/formats/component-story-format) | Non existing feature or undocumented | -| | Stories/MDX syntax | [See current documentation](./api/mdx.md) | [See versioned documentation](https://github.com/storybookjs/storybook/tree/release/5.3/docs/src/pages/formats/mdx-syntax) | Non existing feature or undocumented | -| | Stories/StoriesOF format (see note below) | [See current documentation](../lib/core/docs/storiesOf.md) | [See versioned documentation](https://github.com/storybookjs/storybook/tree/release/5.3/docs/src/pages/formats/storiesof-api) | Non existing feature or undocumented | -| | Frameworks | [See current documentation](./api/new-frameworks.md) | Non existing feature or undocumented | Non existing feature or undocumented | -| | CLI options | [See current documentation](./api/cli-options.md) | [See versioned documentation](https://github.com/storybookjs/storybook/tree/release/5.3/docs/src/pages/configurations/cli-options) | [See versioned documentation](https://github.com/storybookjs/storybook/tree/release/5.0/docs/src/pages/configurations/cli-options) | - +| Section | Page | Current Location | Version 5.3 location | Version 5.0 location | +| ---------------- | ----------------------------------------- | ---------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Get started | Install | [See current documentation](./get-started/install.md) | [See versioned documentation](https://github.com/storybookjs/storybook/tree/release/5.3/docs/src/pages/guides/quick-start-guide) | [See versioned documentation](https://github.com/storybookjs/storybook/tree/release/5.0/docs/src/pages/guides/quick-start-guide) | +| | What's a story | [See current documentation](./get-started/whats-a-story.md) | [See versioned documentation for your framework](https://github.com/storybookjs/storybook/tree/release/5.3/docs/src/pages/guides) | [See versioned documentation for your framework](https://github.com/storybookjs/storybook/tree/release/5.0/docs/src/pages/guides) | +| | Browse Stories | [See current documentation](./get-started/browse-stories.md) | [See versioned documentation for your framework](https://github.com/storybookjs/storybook/tree/release/5.3/docs/src/pages/guides) | [See versioned documentation for your framework](https://github.com/storybookjs/storybook/blob/release/5.0/docs/src/pages/guides) | +| | Setup | [See current documentation](./get-started/setup.md) | [See versioned documentation for your framework](https://github.com/storybookjs/storybook/tree/release/5.3/docs/src/pages/guides) | [See versioned documentation for your framework](https://github.com/storybookjs/storybook/tree/release/5.0/docs/src/pages/guides) | +| Write stories | Introduction | [See current documentation](./writing-stories/introduction.md) | [See versioned documentation](https://github.com/storybookjs/storybook/tree/release/5.3/docs/src/pages/basics/writing-stories) | [See versioned documentation](https://github.com/storybookjs/storybook/tree/release/5.0/docs/src/pages/basics/writing-stories) | +| | Parameters | [See current documentation](./writing-stories/parameters.md) | [See versioned documentation](https://github.com/storybookjs/storybook/tree/release/5.3/docs/src/pages/basics/writing-stories/index.md#parameters) | Non existing feature or undocumented | +| | Decorators | [See current documentation](./writing-stories/decorators.md) | [See versioned documentation](https://github.com/storybookjs/storybook/tree/release/5.3/docs/src/pages/basics/writing-stories/index.md#decorators) | [See versioned documentation](https://github.com/storybookjs/storybook/tree/release/5.0/docs/src/pages/basics/writing-stories/index.md#using-decorators) | +| | Naming components and hierarchy | [See current documentation](./writing-stories/naming-components-and-hierarchy.md) | [See versioned documentation](https://github.com/storybookjs/storybook/tree/release/5.3/docs/src/pages/basics/writing-stories) | [See versioned documentation](https://github.com/storybookjs/storybook/tree/release/5.0/docs/src/pages/basics/writing-stories) | +| | Build pages and screens | [See current documentation](./writing-stories/build-pages-with-storybook.md) | Non existing feature or undocumented | Non existing feature or undocumented | +| | Stories for multiple components | [See current documentation](./writing-stories/stories-for-multiple-components.md) | Non existing feature or undocumented | Non existing feature or undocumented | +| Write docs | DocsPage | [See current documentation](./writing-docs/docs-page.md) | See versioned addon documentation | Non existing feature or undocumented | +| | MDX | [See current documentation](./writing-docs/mdx.md) | See versioned addon documentation | Non existing feature or undocumented | +| | Doc Blocks/Argstable | [See current documentation](./writing-docs/doc-block-argstable.md) | [See versioned addon documentation](https://github.com/storybookjs/storybook/tree/release/5.3/addons/docs/) | Non existing feature or undocumented | +| | Doc Blocks/Canvas | [See current documentation](./writing-docs/doc-block-canvas.md) | [See versioned addon documentation](https://github.com/storybookjs/storybook/tree/release/5.3/addons/docs/) | Non existing feature or undocumented | +| | Doc Blocks/Color Palette | [See current documentation](./writing-docs/doc-block-colorpalette.md) | [See versioned addon documentation](https://github.com/storybookjs/storybook/tree/release/5.3/addons/docs/) | Non existing feature or undocumented | +| | Doc Blocks/Description | [See current documentation](./writing-docs/doc-block-description.md) | [See versioned addon documentation](https://github.com/storybookjs/storybook/tree/release/5.3/addons/docs/) | Non existing feature or undocumented | +| | Doc Blocks/Icon Gallery | [See current documentation](./writing-docs/doc-block-icongallery.md) | [See versioned addon documentation](https://github.com/storybookjs/storybook/tree/release/5.3/addons/docs/) | Non existing feature or undocumented | +| | Doc Blocks/Source | [See current documentation](./writing-docs/doc-block-source.md) | [See versioned addon documentation](https://github.com/storybookjs/storybook/tree/release/5.3/addons/docs/) | Non existing feature or undocumented | +| | Doc Blocks/Story | [See current documentation](./writing-docs/doc-block-story.md) | [See versioned addon documentation](https://github.com/storybookjs/storybook/tree/release/5.3/addons/docs/) | Non existing feature or undocumented | +| | Doc Blocks/Typeset | [See current documentation](./writing-docs/doc-block-typeset.md) | [See versioned addon documentation](https://github.com/storybookjs/storybook/tree/release/5.3/addons/docs/) | Non existing feature or undocumented | +| | Preview and build docs | [See current documentation](./writing-docs/build-documentation.md) | Non existing feature or undocumented | Non existing feature or undocumented | +| Testing | Visual tests | [See current documentation](./writing-tests/visual-testing.md) | [See versioned documentation](https://github.com/storybookjs/storybook/tree/release/5.3/docs/src/pages/testing/automated-visual-testing) | [See versioned documentation](https://github.com/storybookjs/storybook/tree/release/5.0/docs/src/pages/testing/automated-visual-testing) | +| | Accessibility tests | [See current documentation](./writing-tests/accessibility-testing.md) | Non existing feature or undocumented | Non existing feature or undocumented | +| | Interaction tests | [See current documentation](./writing-tests/interaction-testing.md) | [See versioned documentation](https://github.com/storybookjs/storybook/tree/release/5.3/docs/src/pages/testing/interaction-testing) | [See versioned documentation](https://github.com/storybookjs/storybook/tree/release/5.0/docs/src/pages/testing/interaction-testing) | +| | Snapshot tests | [See current documentation](./writing-tests/snapshot-testing.md) | [See versioned documentation](https://github.com/storybookjs/storybook/tree/release/5.3/docs/src/pages/testing/structural-testing) | [See versioned documentation](https://github.com/storybookjs/storybook/tree/release/5.0/docs/src/pages/testing/structural-testing) | +| | Import stories in tests | [See current documentation](./writing-tests/importing-stories-in-tests.md) | [See versioned documentation](https://github.com/storybookjs/storybook/tree/release/5.3/docs/src/pages/testing/react-ui-testing) | [See versioned documentation](https://github.com/storybookjs/storybook/tree/release/5.0/docs/src/pages/testing/react-ui-testing) | +| Sharing | Publish Storybook | [See current documentation](./sharing/publish-storybook.md) | [See versioned documentation](https://github.com/storybookjs/storybook/tree/release/5.3/docs/src/pages/basics/exporting-storybook) | [See versioned documentation](https://github.com/storybookjs/storybook/tree/release/5.0/docs/src/pages/basics/exporting-storybook) | +| | Embed | [See current documentation](./sharing/embed.md) | Non existing feature or undocumented | Non existing feature or undocumented | +| | Composition | [See current documentation](./sharing/storybook-composition.md) | Non existing feature or undocumented | Non existing feature or undocumented | +| | Package Composition | [See current documentation](./sharing/package-composition.md) | Non existing feature or undocumented | Non existing feature or undocumented | +| Essential addons | Controls | [See current documentation](./essentials/controls.md) | Controls are specific to version 6.0 see [Knobs versioned documentation](https://github.com/storybookjs/storybook/tree/release/5.3/addons/knobs) | Controls are specific to version 6.0 see [Knobs versioned documentation](https://github.com/storybookjs/storybook/tree/release/5.0/addons/knobs) | +| | Actions | [See current documentation](./essentials/actions.md) | [See addon versioned documentation](https://github.com/storybookjs/storybook/tree/release/5.3/addons/actions) | [See addon versioned documentation](https://github.com/storybookjs/storybook/tree/release/5.0/addons/actions) | +| | Viewport | [See current documentation](./essentials/viewport.md) | [See addon versioned documentation](https://github.com/storybookjs/storybook/tree/release/5.3/addons/viewport) | [See addon versioned documentation](https://github.com/storybookjs/storybook/tree/release/5.0/addons/viewport) | +| | Backgrounds | [See current documentation](./essentials/backgrounds.md) | [See addon versioned documentation](https://github.com/storybookjs/storybook/tree/release/5.3/addons/backgrounds) | [See addon versioned documentation](https://github.com/storybookjs/storybook/tree/release/5.0/addons/backgrounds) | +| | Toolbars and globals | [See current documentation](./essentials/toolbars-and-globals.md) | [See versioned documentation](https://github.com/storybookjs/storybook/tree/release/5.3/docs/src/pages/basics/toolbar-guide) | Non existing feature or undocumented | +| Configure | Overview | [See current documentation](./configure/overview.md) | [See versioned documentation](https://github.com/storybookjs/storybook/tree/release/5.3/docs/src/pages/configurations/overview) | [See versioned documentation](https://github.com/storybookjs/storybook/tree/release/5.0/docs/src/pages/basics/writing-stories) | +| | Integration/Babel | [See current documentation](./configure/babel.md) | See versioned documentation here and [here](https://github.com/storybookjs/storybook/tree/release/5.3/docs/src/pages/configurations/custom-babel-config) | See versioned documentation here and [here](https://github.com/storybookjs/storybook/tree/release/5.0/docs/src/pages/configurations/custom-babel-config) | +| | Integration/Typescript | [See current documentation](./configure/typescript.md) | [See versioned documentation](https://github.com/storybookjs/storybook/tree/release/5.3/docs/src/pages/configurations/typescript-config) | [See versioned documentation](https://github.com/storybookjs/storybook/tree/release/5.0/docs/src/pages/configurations/typescript-config) | +| | Integration/Styling and CSS | [See current documentation](./configure/styling-and-css.md) | See versioned documentation | See versioned documentation | +| | Integration/Images and assets | [See current documentation](./configure/images-and-assets.md) | See versioned documentation | See versioned documentation | +| | Story rendering | [See current documentation](./configure/story-rendering.md) | See versioned documentation [here](https://github.com/storybookjs/storybook/tree/release/5.3/docs/src/pages/configurations/add-custom-head-tags) and [here](https://github.com/storybookjs/storybook/tree/release/5.3/docs/src/pages/configurations/add-custom-body) | See versioned documentation [here](https://github.com/storybookjs/storybook/tree/release/5.0/docs/src/pages/configurations/add-custom-head-tags) | +| | Story Layout | [See current documentation](./configure/story-layout.md) | Non existing feature or undocumented | Non existing feature or undocumented | +| | User Interface/Features and behavior | [See current documentation](./configure/features-and-behavior.md) | [See versioned documentation](https://github.com/storybookjs/storybook/tree/release/5.3/docs/src/pages/configurations/options-parameter) | [See versioned documentation](https://github.com/storybookjs/storybook/tree/release/5.0/docs/src/pages/configurations/options-parameter) | +| | User Interface/Theming | [See current documentation](./configure/theming.md) | [See versioned documentation](https://github.com/storybookjs/storybook/tree/release/5.3/docs/src/pages/configurations/theming) | [See versioned documentation](https://github.com/storybookjs/storybook/tree/release/5.0/docs/src/pages/configurations/theming) | +| | User Interface/Sidebar & URLS | [See current documentation](./configure/sidebar-and-urls.md) | [See versioned documentation](https://github.com/storybookjs/storybook/tree/release/5.3/docs/src/pages/configurations/options-parameter) | [See versioned documentation](https://github.com/storybookjs/storybook/tree/release/5.0/docs/src/pages/configurations/options-parameter) | +| | Environment variables | [See current documentation](./configure/environment-variables.md) | [See versioned documentation](https://github.com/storybookjs/storybook/tree/release/5.3/docs/src/pages/configurations/env-vars) | [See versioned documentation](https://github.com/storybookjs/storybook/tree/release/5.0/docs/src/pages/configurations/env-vars) | +| Builders | Introduction | [See current documentation](./builders/overview.md) | Non existing feature or undocumented | Non existing feature or undocumented | +| | Vite | [See current documentation](./builders/vite.md) | Non existing feature or undocumented | Non existing feature or undocumented | +| | Webpack | [See current documentation](./builders/webpack.md) | [See versioned documentation](https://github.com/storybookjs/storybook/tree/release/5.3/docs/src/pages/configurations/custom-webpack-config/index.md) | [See versioned documentation](https://github.com/storybookjs/storybook/tree/release/5.0/docs/src/pages/configurations/custom-webpack-config/index.md) | +| | Builder API | [See current documentation](./builders/builder-api.md) | Non existing feature or undocumented | Non existing feature or undocumented | +| Addons | Introduction | [See current documentation](./addons/introduction.md) | [See versioned documentation](https://github.com/storybookjs/storybook/tree/release/5.3/docs/src/pages/addons/writing-addons) | [See versioned documentation](https://github.com/storybookjs/storybook/tree/release/5.0/docs/src/pages/addons/writing-addons) | +| | Install addons | [See current documentation](./addons/install-addons.md) | [See versioned documentation](https://github.com/storybookjs/storybook/tree/release/5.3/docs/src/pages/addons/using-addons/) | [See versioned documentation](https://github.com/storybookjs/storybook/tree/release/5.0/docs/src/pages/addons/using-addons/) | +| | Writing Addons | [See current documentation](./addons/writing-addons.md) | [See versioned documentation](https://github.com/storybookjs/storybook/tree/release/5.3/docs/src/pages/addons/writing-addons) | [See versioned documentation](https://github.com/storybookjs/storybook/tree/release/5.0/docs/src/pages/addons/writing-addons) | +| | Writing Presets | [See current documentation](./addons/writing-presets.md) | [See versioned documentation](https://github.com/storybookjs/storybook/tree/release/5.3/docs/src/pages/presets/writing-presets) | Non existing feature or undocumented | +| | Addons Knowledge Base | [See current documentation](./addons/addon-knowledge-base.md) | [See versioned documentation](https://github.com/storybookjs/storybook/tree/release/5.3/docs/src/pages/addons/writing-addons) | [See versioned documentation](https://github.com/storybookjs/storybook/tree/release/5.0/docs/src/pages/addons/writing-addons) | +| | Types of addons | [See current documentation](./addons/addon-types.md) | Non existing feature or undocumented | Non existing feature or undocumented | +| | Addons API | [See current documentation](./addons/addons-api.md) | [See versioned documentation](https://github.com/storybookjs/storybook/tree/release/5.3/docs/src/pages/addons/api) | [See versioned documentation](https://github.com/storybookjs/storybook/tree/release/5.0/docs/src/pages/addons/api) | +| API | Stories/Component Story Format | [See current documentation](./api/csf.md) | [See versioned documentation](https://github.com/storybookjs/storybook/tree/release/5.3/docs/src/pages/formats/component-story-format) | Non existing feature or undocumented | +| | Stories/MDX syntax | [See current documentation](./api/mdx.md) | [See versioned documentation](https://github.com/storybookjs/storybook/tree/release/5.3/docs/src/pages/formats/mdx-syntax) | Non existing feature or undocumented | +| | Stories/StoriesOF format (see note below) | [See current documentation](https://github.com/storybookjs/storybook/blob/next/lib/core/docs/storiesOf.md) | [See versioned documentation](https://github.com/storybookjs/storybook/tree/release/5.3/docs/src/pages/formats/storiesof-api) | Non existing feature or undocumented | +| | Frameworks | [See current documentation](./api/new-frameworks.md) | Non existing feature or undocumented | Non existing feature or undocumented | +| | CLI options | [See current documentation](./api/cli-options.md) | [See versioned documentation](https://github.com/storybookjs/storybook/tree/release/5.3/docs/src/pages/configurations/cli-options) | [See versioned documentation](https://github.com/storybookjs/storybook/tree/release/5.0/docs/src/pages/configurations/cli-options) |
With the release of version 5.3, we've updated how you can write your stories more compactly and easily. It doesn't mean that the storiesOf format has been removed. For the time being, we're still supporting it, and we have documentation for it. But be advised that this is bound to change in the future. @@ -285,7 +283,6 @@ See our documentation on how to customize the [Storyshots configuration](./writi Currently there's an issue when using MDX stories with IE11. This issue does not apply to [DocsPage](./writing-docs/docs-page.md). If you're interested in helping us fix this issue, read our Contribution guidelines and submit a pull request. - ### Why aren't my code blocks highlighted with Storybook MDX Out of the box, Storybook provides syntax highlighting for a set of languages (e.g., Javascript, Markdown, CSS, HTML, Typescript, GraphQL) that you can use with your code blocks. If you're writing your custom code blocks with MDX, you'll need to import the syntax highlighter manually. For example, if you're adding a code block for SCSS, adjust your story to the following: @@ -341,7 +338,6 @@ You'll need to update it to make it compatible with MDX 2. See the following [issue](https://github.com/mdx-js/mdx/issues/1945) for more information. - ### Why can't I import my own stories into MDX 2? This is a known issue with MDX 2. We're working to fix it. For now you can apply the following workaround: @@ -356,7 +352,6 @@ import * as stories from './Button.stories.jsx'; ``` - ### Why are my mocked GraphQL queries failing with Storybook's MSW addon? If you're working with Vue 3, you'll need to install [`@vue/apollo-composable`](https://www.npmjs.com/package/@vue/apollo-composable). With Svelte, you'll need to install [`@rollup/plugin-replace`](https://www.npmjs.com/package/@rollup/plugin-replace) and update your `rollup.config` file to the following: @@ -399,8 +394,6 @@ Yes, check the [addon's examples](https://github.com/mswjs/msw-storybook-addon/t No, currently, the MSW addon only has support for GraphQL queries. If you're interested in including this feature, open an issue in the [MSW addon repository](https://github.com/mswjs/msw-storybook-addon) and follow up with the maintainer. - - ### How can my code detect if it is running in Storybook? You can do this by checking for the `IS_STORYBOOK` global variable, which will equal `true` when running in Storybook. The environment variable `process.env.STORYBOOK` is also set to `true`. @@ -472,3 +465,15 @@ export default { }, }; ``` + +### Why isn't Storybook's test runner working? + +There's an issue with Storybook's test runner and the latest version of Jest (i.e., version 28), which prevents it from running effectively. As a workaround, you can downgrade Jest to the previous stable version (i.e., version 27), and you'll be able to run it. See the following [issue](https://github.com/storybookjs/test-runner/issues/99) for more information. + +### How does Storybook handles enviroment variables? + +Storybook has built-in support for [environment variables](./configure/environment-variables.md). By default, environment variables are only available in Node.js code and are not available in the browser as some variables should be kept secret (e.g., API keys) and **not** exposed to anyone visiting the published Storybook. + +To expose a variable, you must preface its name with `STORYBOOK_`. So `STORYBOOK_API_URL` will be available in browser code but `API_KEY` will not. Additionally you can also customize which variables are exposed by setting the [`env`](./configure/environment-variables.md#using-storybook-configuration) field in the `.storybook/main.js` file. + +Variables are set when JavaScript is compiled so when the development server is started or you build your Storybook. Environment variable files should not be committed to Git as they often contain secrets which are not safe to add to Git. Instead, add `.env.*` to your `.gitignore` file and set up the environment variables manually on your hosting provider (e.g., [GitHub](https://docs.github.com/en/actions/security-guides/encrypted-secrets#creating-encrypted-secrets-for-a-repository)). diff --git a/docs/frameworks.js b/docs/frameworks.js index e634b6612c45..8d2e1156f7b8 100644 --- a/docs/frameworks.js +++ b/docs/frameworks.js @@ -117,27 +117,27 @@ module.exports = { { name: 'Source', unsupported: [], - path: 'writing-docs/doc-blocks#source', + path: 'writing-docs/doc-block-source', }, { name: 'Dynamic source', supported: ['react', 'vue', 'angular', 'svelte', 'web-components', 'html'], - path: 'writing-docs/doc-blocks#source', + path: 'writing-docs/doc-block-source', }, { name: 'Args Table', supported: ['react', 'vue', 'angular', 'html', 'ember', 'web-components', 'svelte'], - path: 'writing-docs/doc-blocks#argstable', + path: 'writing-docs/doc-block-argstable', }, { name: 'Description', supported: ['react', 'vue', 'angular', 'ember', 'web-components'], - path: 'writing-docs/doc-blocks#description', + path: 'writing-docs/doc-block-description', }, { name: 'Inline stories', supported: ['react', 'vue', 'web-components', 'html', 'svelte', 'angular'], - path: 'writing-docs/doc-blocks#inline-rendering', + path: 'writing-docs/docs-page#inline-stories-vs-iframe-stories', }, ], }, diff --git a/docs/get-started/install.md b/docs/get-started/install.md index be09b6b2a85f..8c5fe9ae609d 100644 --- a/docs/get-started/install.md +++ b/docs/get-started/install.md @@ -90,7 +90,9 @@ Below are some of the most common installation issues and instructions on how to
+ Storybook collects completely anonymous data to help us improve user experience. Participation is optional, and you may [opt-out](../configure/telemetry.md#how-to-opt-out) if you'd not like to share any information. +
If all else fails, try asking for [help](https://storybook.js.org/support) diff --git a/docs/get-started/installation-problems/angular.mdx b/docs/get-started/installation-problems/angular.mdx index 773e23f801ac..c0c463e548bf 100644 --- a/docs/get-started/installation-problems/angular.mdx +++ b/docs/get-started/installation-problems/angular.mdx @@ -1,3 +1,10 @@ +- Storybook's CLI provides support for both [Yarn](https://yarnpkg.com/) and [npm](https://www.npmjs.com/) package managers. + If you have Yarn installed in your environment but prefer to use npm as your default package manager add the `--use-npm` flag to your installation command. For example: + + ```shell + npx storybook init --use-npm + ``` + - Add the `--type angular` flag to the installation command to set up Storybook manually: ```shell diff --git a/docs/get-started/installation-problems/ember.mdx b/docs/get-started/installation-problems/ember.mdx index 23856fe3d542..7a7698e3d84b 100644 --- a/docs/get-started/installation-problems/ember.mdx +++ b/docs/get-started/installation-problems/ember.mdx @@ -1,3 +1,10 @@ +- Storybook's CLI provides support for both [Yarn](https://yarnpkg.com/) and [npm](https://www.npmjs.com/) package managers. + If you have Yarn installed in your environment but prefer to use npm as your default package manager add the `--use-npm` flag to your installation command. For example: + + ```shell + npx storybook init --use-npm + ``` + - Add the `--type ember` flag to the installation command to set up Storybook manually: ```shell diff --git a/docs/get-started/installation-problems/preact.mdx b/docs/get-started/installation-problems/preact.mdx index 3b1a2b94a1bd..593f0c13ef33 100644 --- a/docs/get-started/installation-problems/preact.mdx +++ b/docs/get-started/installation-problems/preact.mdx @@ -1,3 +1,10 @@ +- Storybook's CLI provides support for both [Yarn](https://yarnpkg.com/) and [npm](https://www.npmjs.com/) package managers. + If you have Yarn installed in your environment but prefer to use npm as your default package manager add the `--use-npm` flag to your installation command. For example: + + ```shell + npx storybook init --use-npm + ``` + - Add the `--type preact` flag to the installation command to set up Storybook manually: ```shell diff --git a/docs/get-started/installation-problems/react.mdx b/docs/get-started/installation-problems/react.mdx index 36f517bcdaff..0acc6ef29f97 100644 --- a/docs/get-started/installation-problems/react.mdx +++ b/docs/get-started/installation-problems/react.mdx @@ -1,3 +1,10 @@ +- Storybook's CLI provides support for both [Yarn](https://yarnpkg.com/) and [npm](https://www.npmjs.com/) package managers. + If you have Yarn installed in your environment but prefer to use npm as your default package manager add the `--use-npm` flag to your installation command. For example: + + ```shell + npx storybook init --use-npm + ``` + - Add the `--type react` flag to the installation command to set up Storybook manually: ```shell diff --git a/docs/get-started/installation-problems/svelte.mdx b/docs/get-started/installation-problems/svelte.mdx index 2b53693d98c8..68f248b11ec8 100644 --- a/docs/get-started/installation-problems/svelte.mdx +++ b/docs/get-started/installation-problems/svelte.mdx @@ -1,3 +1,10 @@ +- Storybook's CLI provides support for both [Yarn](https://yarnpkg.com/) and [npm](https://www.npmjs.com/) package managers. + If you have Yarn installed in your environment but prefer to use npm as your default package manager add the `--use-npm` flag to your installation command. For example: + + ```shell + npx storybook init --use-npm + ``` + - Add the `--type svelte` flag to the installation command to set up Storybook manually: ```shell diff --git a/docs/get-started/installation-problems/vue.mdx b/docs/get-started/installation-problems/vue.mdx index 61ab98ead519..d0c276ff4970 100644 --- a/docs/get-started/installation-problems/vue.mdx +++ b/docs/get-started/installation-problems/vue.mdx @@ -1,3 +1,10 @@ +- Storybook's CLI provides support for both [Yarn](https://yarnpkg.com/) and [npm](https://www.npmjs.com/) package managers. + If you have Yarn installed in your environment but prefer to use npm as your default package manager add the `--use-npm` flag to your installation command. For example: + + ```shell + npx storybook init --use-npm + ``` + - Add the `--type vue` (for Vue 2), or `--type vue3` (for Vue 3) flag to the installation command to set up Storybook manually: ```shell diff --git a/docs/get-started/whats-a-story.md b/docs/get-started/whats-a-story.md index 8425cc063cfc..c349c1768787 100644 --- a/docs/get-started/whats-a-story.md +++ b/docs/get-started/whats-a-story.md @@ -93,6 +93,6 @@ Stories are also helpful for checking that UI continues to look correct as you m /> -Checking component’s stories as you develop helps prevent accidental regressions. Tools that integrate with Storybook can also [automate](../writing-tests/introduction.md) this for you. +Checking component’s stories as you develop helps prevent accidental regressions. [Tools that integrate with Storybook can automate this](../writing-tests/introduction.md) for you. Now that we’ve seen the basic anatomy of a story let’s see how we use Storybook’s UI to develop stories. diff --git a/docs/sharing/publish-storybook.md b/docs/sharing/publish-storybook.md index f260dc6f99aa..2e6794a0a923 100644 --- a/docs/sharing/publish-storybook.md +++ b/docs/sharing/publish-storybook.md @@ -21,7 +21,8 @@ First, we'll need to build Storybook as a static web application. The functional paths={[ 'angular/custom-build-script-production.script-for-builder.js.mdx', 'angular/build-storybook-production-mode.with-builder.js.mdx', - 'common/build-storybook-production-mode.js.mdx', + 'common/build-storybook-production-mode.yarn.js.mdx', + 'common/build-storybook-production-mode.npm.js.mdx', ]} /> @@ -49,13 +50,16 @@ To get started, sign up with your GitHub, GitLab, Bitbucket, or email and genera Next, install the [Chromatic CLI](https://www.npmjs.com/package/chromatic) package from npm: -```shell -# With npm -npm install --save-dev chromatic + -# With yarn -yarn add --dev chromatic -``` + + + Run the following command after the package finishes installing. Make sure that you replace `your-project-token` with your own project token. diff --git a/docs/snippets/common/build-storybook-production-mode.js.mdx b/docs/snippets/common/build-storybook-production-mode.js.mdx deleted file mode 100644 index 9bd298812fa9..000000000000 --- a/docs/snippets/common/build-storybook-production-mode.js.mdx +++ /dev/null @@ -1,7 +0,0 @@ -```shell -# With yarn -yarn build-storybook - -# With npm -npm run build-storybook -``` \ No newline at end of file diff --git a/docs/snippets/common/build-storybook-production-mode.npm.js.mdx b/docs/snippets/common/build-storybook-production-mode.npm.js.mdx new file mode 100644 index 000000000000..15ee902eae48 --- /dev/null +++ b/docs/snippets/common/build-storybook-production-mode.npm.js.mdx @@ -0,0 +1,3 @@ +```shell +npm run build-storybook +``` \ No newline at end of file diff --git a/docs/snippets/common/build-storybook-production-mode.yarn.js.mdx b/docs/snippets/common/build-storybook-production-mode.yarn.js.mdx new file mode 100644 index 000000000000..eda3dbd3ad90 --- /dev/null +++ b/docs/snippets/common/build-storybook-production-mode.yarn.js.mdx @@ -0,0 +1,3 @@ +```shell +yarn build-storybook +``` \ No newline at end of file diff --git a/docs/snippets/common/button-story-project-args-theme.js.mdx b/docs/snippets/common/button-story-project-args-theme.js.mdx index da897c5a7829..c3fd8bd5e666 100644 --- a/docs/snippets/common/button-story-project-args-theme.js.mdx +++ b/docs/snippets/common/button-story-project-args-theme.js.mdx @@ -2,7 +2,7 @@ // preview.js // All stories expect a theme arg -export const argTypes = { theme: { control: { options: ['light', 'dark'] } } }; +export const argTypes = { theme: { control: 'select', options: ['light', 'dark'] } }; // The default value of the theme arg to all stories export const args = { theme: 'light' }; diff --git a/docs/snippets/common/chromatic-install.npm.js.mdx b/docs/snippets/common/chromatic-install.npm.js.mdx new file mode 100644 index 000000000000..08f68adbfcc0 --- /dev/null +++ b/docs/snippets/common/chromatic-install.npm.js.mdx @@ -0,0 +1,3 @@ +```shell +npm install chromatic --save-dev +``` \ No newline at end of file diff --git a/docs/snippets/common/chromatic-install.yarn.js.mdx b/docs/snippets/common/chromatic-install.yarn.js.mdx new file mode 100644 index 000000000000..ef2232eb8816 --- /dev/null +++ b/docs/snippets/common/chromatic-install.yarn.js.mdx @@ -0,0 +1,3 @@ +```shell +yarn add --dev chromatic +``` \ No newline at end of file diff --git a/docs/snippets/common/storybook-addon-actions-install.npm.js.mdx b/docs/snippets/common/storybook-addon-actions-install.npm.js.mdx new file mode 100644 index 000000000000..a693fd458d6b --- /dev/null +++ b/docs/snippets/common/storybook-addon-actions-install.npm.js.mdx @@ -0,0 +1,3 @@ +```shell +npm install @storybook/addon-actions --save-dev +``` \ No newline at end of file diff --git a/docs/snippets/common/storybook-addon-actions-install.yarn.js.mdx b/docs/snippets/common/storybook-addon-actions-install.yarn.js.mdx new file mode 100644 index 000000000000..b1e52357c623 --- /dev/null +++ b/docs/snippets/common/storybook-addon-actions-install.yarn.js.mdx @@ -0,0 +1,3 @@ +```shell +yarn add --dev @storybook/addon-actions +``` \ No newline at end of file diff --git a/docs/snippets/common/storybook-addon-essentials-install.npm.js.mdx b/docs/snippets/common/storybook-addon-essentials-install.npm.js.mdx new file mode 100644 index 000000000000..a693fd458d6b --- /dev/null +++ b/docs/snippets/common/storybook-addon-essentials-install.npm.js.mdx @@ -0,0 +1,3 @@ +```shell +npm install @storybook/addon-actions --save-dev +``` \ No newline at end of file diff --git a/docs/snippets/common/storybook-addon-essentials-install.yarn.js.mdx b/docs/snippets/common/storybook-addon-essentials-install.yarn.js.mdx new file mode 100644 index 000000000000..7bc9cf52e948 --- /dev/null +++ b/docs/snippets/common/storybook-addon-essentials-install.yarn.js.mdx @@ -0,0 +1,3 @@ +```shell +yarn add --dev @storybook/addon-essentials +``` \ No newline at end of file diff --git a/docs/snippets/common/storybook-addon-storyshots-install.npm.js.mdx b/docs/snippets/common/storybook-addon-storyshots-install.npm.js.mdx new file mode 100644 index 000000000000..1d4b6caf3acc --- /dev/null +++ b/docs/snippets/common/storybook-addon-storyshots-install.npm.js.mdx @@ -0,0 +1,3 @@ +```shell +npm install @storybook/addon-storyshots --save-dev +``` \ No newline at end of file diff --git a/docs/snippets/common/storybook-addon-storyshots-install.yarn.js.mdx b/docs/snippets/common/storybook-addon-storyshots-install.yarn.js.mdx new file mode 100644 index 000000000000..c847016ced68 --- /dev/null +++ b/docs/snippets/common/storybook-addon-storyshots-install.yarn.js.mdx @@ -0,0 +1,3 @@ +```shell +yarn add --dev @storybook/addon-storyshots +``` \ No newline at end of file diff --git a/docs/snippets/common/storybook-debug-webpack-dev.npm.js.mdx b/docs/snippets/common/storybook-debug-webpack-dev.npm.js.mdx new file mode 100644 index 000000000000..080af4a1debf --- /dev/null +++ b/docs/snippets/common/storybook-debug-webpack-dev.npm.js.mdx @@ -0,0 +1,3 @@ +```shell +npm run storybook -- --debug-webpack +``` \ No newline at end of file diff --git a/docs/snippets/common/storybook-debug-webpack-dev.yarn.js.mdx b/docs/snippets/common/storybook-debug-webpack-dev.yarn.js.mdx new file mode 100644 index 000000000000..8dbc7b2b49e4 --- /dev/null +++ b/docs/snippets/common/storybook-debug-webpack-dev.yarn.js.mdx @@ -0,0 +1,3 @@ +```shell +yarn storybook --debug-webpack +``` \ No newline at end of file diff --git a/docs/snippets/common/storybook-debug-webpack-prod.npm.js.mdx b/docs/snippets/common/storybook-debug-webpack-prod.npm.js.mdx new file mode 100644 index 000000000000..5ca3edbb934f --- /dev/null +++ b/docs/snippets/common/storybook-debug-webpack-prod.npm.js.mdx @@ -0,0 +1,3 @@ +```shell +npm run build-storybook -- --debug-webpack +``` \ No newline at end of file diff --git a/docs/snippets/common/storybook-debug-webpack-prod.yarn.js.mdx b/docs/snippets/common/storybook-debug-webpack-prod.yarn.js.mdx new file mode 100644 index 000000000000..1b2c9df57924 --- /dev/null +++ b/docs/snippets/common/storybook-debug-webpack-prod.yarn.js.mdx @@ -0,0 +1,3 @@ +```shell +yarn build-storybook --debug-webpack +``` \ No newline at end of file diff --git a/docs/snippets/common/storybook-main-enable-transcludemarkdown.js.mdx b/docs/snippets/common/storybook-main-enable-transcludemarkdown.js.mdx index ab8a8a2b063e..cb07d5763454 100644 --- a/docs/snippets/common/storybook-main-enable-transcludemarkdown.js.mdx +++ b/docs/snippets/common/storybook-main-enable-transcludemarkdown.js.mdx @@ -1,3 +1,4 @@ +```js // .storybook/main.js|ts module.exports = { @@ -17,4 +18,5 @@ module.exports = { }, }, ], -}; \ No newline at end of file +}; +``` diff --git a/docs/snippets/common/storybook-main-with-single-static-dir.js.mdx b/docs/snippets/common/storybook-main-with-single-static-dir.js.mdx index 51f72b251d8f..12ca0636ba6b 100644 --- a/docs/snippets/common/storybook-main-with-single-static-dir.js.mdx +++ b/docs/snippets/common/storybook-main-with-single-static-dir.js.mdx @@ -2,8 +2,8 @@ // .storybook/main.js module.exports = { - stories: [], - addons: [], - staticDirs: ['../public'], + stories: ['../src/**/*.stories.mdx', '../src/**/*.stories.@(js|jsx|ts|tsx)'], + addons: ['@storybook/addon-links', '@storybook/addon-essentials'], + staticDirs: ['../public'], //👈 Configures the static asset folder in Storybook }; ``` \ No newline at end of file diff --git a/docs/snippets/common/storybook-msw-generate.msw.js.mdx b/docs/snippets/common/storybook-msw-generate.msw.js.mdx new file mode 100644 index 000000000000..413d5bf267e2 --- /dev/null +++ b/docs/snippets/common/storybook-msw-generate.msw.js.mdx @@ -0,0 +1,3 @@ +```shell +npx msw init public/ +``` \ No newline at end of file diff --git a/docs/snippets/common/storybook-msw-install.npm.js.mdx b/docs/snippets/common/storybook-msw-install.npm.js.mdx new file mode 100644 index 000000000000..2a8608ebb293 --- /dev/null +++ b/docs/snippets/common/storybook-msw-install.npm.js.mdx @@ -0,0 +1,3 @@ +```shell +npm install msw msw-storybook-addon --save-dev +``` \ No newline at end of file diff --git a/docs/snippets/common/storybook-msw-install.yarn.js.mdx b/docs/snippets/common/storybook-msw-install.yarn.js.mdx new file mode 100644 index 000000000000..ff285f0d7176 --- /dev/null +++ b/docs/snippets/common/storybook-msw-install.yarn.js.mdx @@ -0,0 +1,3 @@ +```shell +yarn add --dev msw msw-storybook-addon +``` \ No newline at end of file diff --git a/docs/snippets/common/storybook-preview-register-msw-addon.js.mdx b/docs/snippets/common/storybook-preview-register-msw-addon.js.mdx new file mode 100644 index 000000000000..d1b97095311a --- /dev/null +++ b/docs/snippets/common/storybook-preview-register-msw-addon.js.mdx @@ -0,0 +1,25 @@ +```js +// .storybook/preview.js + +import { initialize, mswDecorator } from 'msw-storybook-addon'; + +/* + * Initializes MSW + * See https://github.com/mswjs/msw-storybook-addon#configuring-msw + * to learn how to customize it + */ +initialize(); + +export const parameters = { + actions: { argTypesRegex: '^on[A-Z].*' }, + controls: { + matchers: { + color: /(background|color)$/i, + date: /Date$/, + }, + }, +}; + +// Provide the MSW addon decorator globally +export const decorators = [mswDecorator]; +``` \ No newline at end of file diff --git a/docs/snippets/common/storybook-test-runner-install.npm.js.mdx b/docs/snippets/common/storybook-test-runner-install.npm.js.mdx index 90f046c3ec62..50b39891c2b2 100644 --- a/docs/snippets/common/storybook-test-runner-install.npm.js.mdx +++ b/docs/snippets/common/storybook-test-runner-install.npm.js.mdx @@ -1,3 +1,3 @@ ```shell -npm install @storybook/test-runner jest --save-dev +npm install @storybook/test-runner jest@27 --save-dev ``` \ No newline at end of file diff --git a/docs/snippets/common/storybook-test-runner-install.yarn.js.mdx b/docs/snippets/common/storybook-test-runner-install.yarn.js.mdx index 3221e525779e..79840bb5b1b7 100644 --- a/docs/snippets/common/storybook-test-runner-install.yarn.js.mdx +++ b/docs/snippets/common/storybook-test-runner-install.yarn.js.mdx @@ -1,3 +1,3 @@ ```shell -yarn add --dev @storybook/test-runner jest +yarn add --dev @storybook/test-runner jest@27 ``` \ No newline at end of file diff --git a/docs/snippets/common/storybook-vite-builder-aliasing.js.mdx b/docs/snippets/common/storybook-vite-builder-aliasing.js.mdx index af94f7ec987d..223d5bb2a4a1 100644 --- a/docs/snippets/common/storybook-vite-builder-aliasing.js.mdx +++ b/docs/snippets/common/storybook-vite-builder-aliasing.js.mdx @@ -13,7 +13,7 @@ module.exports = { // Merge custom configuration into the default config return mergeConfig(config, { // Use the same "resolve" configuration as your app - resolve: (await import('../vite.config.js')).default.resolve + resolve: (await import('../vite.config.js')).default.resolve, // Add dependencies to pre-optimization optimizeDeps: { include: ['storybook-dark-mode'], diff --git a/docs/snippets/common/storybook-write-addon-install-dependencies.npm.js.mdx b/docs/snippets/common/storybook-write-addon-install-dependencies.npm.js.mdx new file mode 100644 index 000000000000..e196ab444371 --- /dev/null +++ b/docs/snippets/common/storybook-write-addon-install-dependencies.npm.js.mdx @@ -0,0 +1,3 @@ +```shell +npm install react react-dom @babel/cli +``` \ No newline at end of file diff --git a/docs/snippets/common/storybook-write-addon-install-dependencies.yarn.js.mdx b/docs/snippets/common/storybook-write-addon-install-dependencies.yarn.js.mdx new file mode 100644 index 000000000000..e81984d3e2a2 --- /dev/null +++ b/docs/snippets/common/storybook-write-addon-install-dependencies.yarn.js.mdx @@ -0,0 +1,3 @@ +```shell +yarn add react react-dom @babel/cli +``` \ No newline at end of file diff --git a/docs/snippets/html/button-story-component-decorator.js.mdx b/docs/snippets/html/button-story-component-decorator.js.mdx new file mode 100644 index 000000000000..c87cb62adbb8 --- /dev/null +++ b/docs/snippets/html/button-story-component-decorator.js.mdx @@ -0,0 +1,21 @@ +```js +// Button.stories.js + +import { createButton } from './Button'; + +export default { + /* 👇 The title prop is optional. + * See https://storybook.js.org/docs/html/configure/overview#configure-story-loading + * to learn how to generate automatic titles + */ + title: 'Button', + decorators: [(story) => { + const decorator = document.createElement('div'); + decorator.style.margin = '3em'; + decorator.appendChild(story()); + return decorator; + }], +}; + +export const Primary = (args) => createButton(args); +``` diff --git a/docs/snippets/html/button-story-component-decorator.ts.mdx b/docs/snippets/html/button-story-component-decorator.ts.mdx new file mode 100644 index 000000000000..d1a4efaa4258 --- /dev/null +++ b/docs/snippets/html/button-story-component-decorator.ts.mdx @@ -0,0 +1,23 @@ +```ts +// Button.stories.ts + +import { Meta, StoryFn } from '@storybook/html'; + +import { createButton, ButtonArgs } from './Button'; + +export default { + /* 👇 The title prop is optional. + * See https://storybook.js.org/docs/html/configure/overview#configure-story-loading + * to learn how to generate automatic titles + */ + title: 'Button', + decorators: [(story) => { + const decorator = document.createElement('div'); + decorator.style.margin = '3em'; + decorator.appendChild(story()); + return decorator; + }], +} as Meta; + +export const Primary: StoryFn = (args) => createButton(args); +``` diff --git a/docs/snippets/html/button-story-default-exports.js.mdx b/docs/snippets/html/button-story-default-exports.js.mdx new file mode 100644 index 000000000000..c6bbe5bf64f1 --- /dev/null +++ b/docs/snippets/html/button-story-default-exports.js.mdx @@ -0,0 +1,13 @@ +```js +// Button.stories.js + +import { createButton } from './Button'; + +export default { + /* 👇 The title prop is optional. + * See https://storybook.js.org/docs/html/configure/overview#configure-story-loading + * to learn how to generate automatic titles + */ + title: 'Button', +}; +``` diff --git a/docs/snippets/html/button-story-default-exports.ts.mdx b/docs/snippets/html/button-story-default-exports.ts.mdx new file mode 100644 index 000000000000..e294d98b1b40 --- /dev/null +++ b/docs/snippets/html/button-story-default-exports.ts.mdx @@ -0,0 +1,15 @@ +```ts +// Button.stories.ts + +import { Meta } from '@storybook/html'; + +import { createButton, ButtonArgs } from './Button'; + +export default { + /* 👇 The title prop is optional. + * See https://storybook.js.org/docs/html/configure/overview#configure-story-loading + * to learn how to generate automatic titles + */ + title: 'Button', +} as Meta; +``` diff --git a/docs/snippets/html/button-story-rename-story.js.mdx b/docs/snippets/html/button-story-rename-story.js.mdx new file mode 100644 index 000000000000..3f13f148ce43 --- /dev/null +++ b/docs/snippets/html/button-story-rename-story.js.mdx @@ -0,0 +1,16 @@ +```js +// Button.stories.js + +import { createButton } from './Button'; + +export default { + /* 👇 The title prop is optional. + * See https://storybook.js.org/docs/html/configure/overview#configure-story-loading + * to learn how to generate automatic titles + */ + title: 'Button', +}; + +export const Primary = (args) => createButton(args); +Primary.storyName = 'I am the primary'; +``` diff --git a/docs/snippets/html/button-story-rename-story.ts.mdx b/docs/snippets/html/button-story-rename-story.ts.mdx new file mode 100644 index 000000000000..0b37196b9a41 --- /dev/null +++ b/docs/snippets/html/button-story-rename-story.ts.mdx @@ -0,0 +1,18 @@ +```ts +// Button.stories.ts + +import { Meta, StoryFn } from '@storybook/html'; + +import { createButton, ButtonArgs } from './Button'; + +export default { + /* 👇 The title prop is optional. + * See https://storybook.js.org/docs/html/configure/overview#configure-story-loading + * to learn how to generate automatic titles + */ + title: 'Button', +} as Meta; + +export const Primary: StoryFn = (args) => createButton(args); +Primary.storyName = 'I am the primary'; +``` diff --git a/docs/snippets/html/button-story-using-args.js.mdx b/docs/snippets/html/button-story-using-args.js.mdx new file mode 100644 index 000000000000..9df04fd6e394 --- /dev/null +++ b/docs/snippets/html/button-story-using-args.js.mdx @@ -0,0 +1,26 @@ +```js +// Button.stories.js + +import { createButton } from './Button'; + +export default { + /* 👇 The title prop is optional. + * See https://storybook.js.org/docs/html/configure/overview#configure-story-loading + * to learn how to generate automatic titles + */ + title: 'Button', +}; + +//👇 We create a “template” of how args map to rendering +const Template = (args) => createButton(args); + +//👇 Each story then reuses that template +export const Primary = Template.bind({}); +Primary.args = { primary: true, label: 'Button' }; + +export const Secondary = Template.bind({}); +Secondary.args = { ...Primary.args, label: '😄👍😍💯' }; + +export const Tertiary = Template.bind({}); +Tertiary.args = { ...Primary.args, label: '📚📕📈🤓' }; +``` diff --git a/docs/snippets/html/button-story-using-args.ts.mdx b/docs/snippets/html/button-story-using-args.ts.mdx new file mode 100644 index 000000000000..759858bf1da4 --- /dev/null +++ b/docs/snippets/html/button-story-using-args.ts.mdx @@ -0,0 +1,27 @@ +```ts +// Button.stories.ts + +import { Meta, StoryFn } from '@storybook/html'; +import { createButton, ButtonArgs } from './Button'; + +export default { + /* 👇 The title prop is optional. + * See https://storybook.js.org/docs/html/configure/overview#configure-story-loading + * to learn how to generate automatic titles + */ + title: 'Button', +} as Meta; + +//👇 We create a “template” of how args map to rendering +const Template: StoryFn = (args): HTMLButtonElement => createButton(args); + +//👇 Each story then reuses that template +export const Primary = Template.bind({}); +Primary.args = { primary: true, label: 'Button' }; + +export const Secondary = Template.bind({}); +Secondary.args = { ...Primary.args, label: '😄👍😍💯' }; + +export const Tertiary = Template.bind({}); +Tertiary.args = { ...Primary.args, label: '📚📕📈🤓' }; +``` diff --git a/docs/snippets/html/button-story-with-args.js.mdx b/docs/snippets/html/button-story-with-args.js.mdx index 60feb2014547..8d71b288cef9 100644 --- a/docs/snippets/html/button-story-with-args.js.mdx +++ b/docs/snippets/html/button-story-with-args.js.mdx @@ -1,4 +1,6 @@ ```js +// Button.stories.js + export default { /* 👇 The title prop is optional. * See https://storybook.js.org/docs/html/configure/overview#configure-story-loading diff --git a/docs/snippets/html/button-story-with-args.ts.mdx b/docs/snippets/html/button-story-with-args.ts.mdx index 3130fc260de7..9b75446177ee 100644 --- a/docs/snippets/html/button-story-with-args.ts.mdx +++ b/docs/snippets/html/button-story-with-args.ts.mdx @@ -1,16 +1,23 @@ ```ts +// Button.stories.ts + import { Meta, StoryFn } from '@storybook/html'; +type ButtonArgs = { + primary: boolean; + label: string; +} + export default { /* 👇 The title prop is optional. * See https://storybook.js.org/docs/html/configure/overview#configure-story-loading * to learn how to generate automatic titles */ title: 'Button', -} as Meta; +} as Meta; //👇 We create a “template” of how args map to rendering -const Template: StoryFn = (args): HTMLButtonElement => { +const Template: StoryFn = (args): HTMLButtonElement => { const btn = document.createElement('button'); btn.innerText = args.label; diff --git a/docs/snippets/html/button-story-with-blue-args.js.mdx b/docs/snippets/html/button-story-with-blue-args.js.mdx new file mode 100644 index 000000000000..5cb8981ad168 --- /dev/null +++ b/docs/snippets/html/button-story-with-blue-args.js.mdx @@ -0,0 +1,25 @@ +```js +// Button.stories.js + +import { createButton } from './Button'; + +export default { + /* 👇 The title prop is optional. + * See https://storybook.js.org/docs/html/configure/overview#configure-story-loading + * to learn how to generate automatic titles + */ + title: 'Button', + //👇 Creates specific parameters for the story + parameters: { + backgrounds: { + values: [ + { name: 'red', value: '#f00' }, + { name: 'green', value: '#0f0' }, + { name: 'blue', value: '#00f' }, + ], + }, + }, +}; + +export const Primary = (args) => createButton(args); +``` diff --git a/docs/snippets/html/button-story-with-blue-args.ts.mdx b/docs/snippets/html/button-story-with-blue-args.ts.mdx new file mode 100644 index 000000000000..906845b4f472 --- /dev/null +++ b/docs/snippets/html/button-story-with-blue-args.ts.mdx @@ -0,0 +1,27 @@ +```ts +// Button.stories.ts + +import { Meta, StoryFn } from '@storybook/html'; + +import { createButton, ButtonArgs } from './Button'; + +export default { + /* 👇 The title prop is optional. + * See https://storybook.js.org/docs/html/configure/overview#configure-story-loading + * to learn how to generate automatic titles + */ + title: 'Button', + //👇 Creates specific parameters for the story + parameters: { + backgrounds: { + values: [ + { name: 'red', value: '#f00' }, + { name: 'green', value: '#0f0' }, + { name: 'blue', value: '#00f' }, + ], + }, + }, +} as Meta; + +export const Primary: StoryFn = (args) => createButton(args); +``` diff --git a/docs/snippets/html/button-story-with-emojis.js.mdx b/docs/snippets/html/button-story-with-emojis.js.mdx new file mode 100644 index 000000000000..b6b9b43ec295 --- /dev/null +++ b/docs/snippets/html/button-story-with-emojis.js.mdx @@ -0,0 +1,16 @@ +```js +// Button.stories.js + +import { createButton } from './Button'; + +export default { + /* 👇 The title prop is optional. + * See https://storybook.js.org/docs/html/configure/overview#configure-story-loading + * to learn how to generate automatic titles + */ + title: 'Button', +}; +export const Primary = () => createButton({ backgroundColor: "#ff0", label: "Button"}); +export const Secondary = () => createButton({ backgroundColor: "#ff0", label: "😄👍😍💯"}); +export const Tertiary = () => createButton({ backgroundColor: "#ff0", label: "📚📕📈🤓"}); +``` diff --git a/docs/snippets/html/button-story-with-emojis.ts.mdx b/docs/snippets/html/button-story-with-emojis.ts.mdx new file mode 100644 index 000000000000..47a1f99f8ee1 --- /dev/null +++ b/docs/snippets/html/button-story-with-emojis.ts.mdx @@ -0,0 +1,17 @@ +```ts +// Button.stories.ts + +import { Meta, StoryFn } from '@storybook/html'; +import { createButton, ButtonArgs } from './Button'; + +export default { + /* 👇 The title prop is optional. + * See https://storybook.js.org/docs/html/configure/overview#configure-story-loading + * to learn how to generate automatic titles + */ + title: 'Button', +} as Meta; +export const Primary: StoryFn = () => createButton({ backgroundColor: "#ff0", label: "Button"}); +export const Secondary: StoryFn = () => createButton({ backgroundColor: "#ff0", label: "😄👍😍💯"}); +export const Tertiary: StoryFn = () => createButton({ backgroundColor: "#ff0", label: "📚📕📈🤓"}); +``` diff --git a/docs/snippets/html/button-story.js.mdx b/docs/snippets/html/button-story.js.mdx index 743c489eff80..6268687c428b 100644 --- a/docs/snippets/html/button-story.js.mdx +++ b/docs/snippets/html/button-story.js.mdx @@ -1,4 +1,6 @@ ```js +// Button.stories.js + export default { /* 👇 The title prop is optional. * See https://storybook.js.org/docs/html/configure/overview#configure-story-loading diff --git a/docs/snippets/html/button-story.ts.mdx b/docs/snippets/html/button-story.ts.mdx index 104aa6ccbd19..62e72638171e 100644 --- a/docs/snippets/html/button-story.ts.mdx +++ b/docs/snippets/html/button-story.ts.mdx @@ -1,4 +1,6 @@ ```ts +// Button.stories.ts + import { Meta, StoryFn } from '@storybook/html'; export default { diff --git a/docs/snippets/html/list-story-expanded.js.mdx b/docs/snippets/html/list-story-expanded.js.mdx new file mode 100644 index 000000000000..b9cbe7d627f1 --- /dev/null +++ b/docs/snippets/html/list-story-expanded.js.mdx @@ -0,0 +1,27 @@ + +```js +// List.stories.js + +import { createList } from './List'; +import { createListItem } from './ListItem'; + +export default { + title: 'List', +}; + +export const Empty = (args) => createList(args); + +export const OneItem = (args) => { + const list = createList(args); + list.appendChild(createListItem()); + return list; +}; + +export const ManyItems = (args) => { + const list = createList(args); + list.appendChild(createListItem()); + list.appendChild(createListItem()); + list.appendChild(createListItem()); + return list; +}; +``` diff --git a/docs/snippets/html/list-story-expanded.ts.mdx b/docs/snippets/html/list-story-expanded.ts.mdx new file mode 100644 index 000000000000..81e14d1162a4 --- /dev/null +++ b/docs/snippets/html/list-story-expanded.ts.mdx @@ -0,0 +1,29 @@ + +```ts +// List.stories.ts + +import { Meta, StoryFn } from '@storybook/html'; + +import { createList, ListArgs } from './List'; +import { createListItem } from './ListItem'; + +export default { + title: 'List', +} as Meta; + +export const Empty: StoryFn = (args) => createList(args); + +export const OneItem: StoryFn = (args) => { + const list = createList(args); + list.appendChild(createListItem()); + return list; +}; + +export const ManyItems: StoryFn = (args) => { + const list = createList(args); + list.appendChild(createListItem()); + list.appendChild(createListItem()); + list.appendChild(createListItem()); + return list; +}; +``` diff --git a/docs/snippets/html/list-story-reuse-data.js.mdx b/docs/snippets/html/list-story-reuse-data.js.mdx new file mode 100644 index 000000000000..a58833617912 --- /dev/null +++ b/docs/snippets/html/list-story-reuse-data.js.mdx @@ -0,0 +1,22 @@ + +```js +// List.stories.js + +import { createList } from './List'; +import { createListItem } from './ListItem'; + +// 👇 We're importing the necessary stories from ListItem +import { Selected, Unselected } from './ListItem.stories'; + +export default { + title: 'List', +}; + +export const ManyItems = (args) => { + const list = createList(args); + list.appendChild(createListItem(Selected.args)); + list.appendChild(createListItem(Unselected.args)); + list.appendChild(createListItem(Unselected.args)); + return list; +}; +``` diff --git a/docs/snippets/html/list-story-reuse-data.ts.mdx b/docs/snippets/html/list-story-reuse-data.ts.mdx new file mode 100644 index 000000000000..434bec00d690 --- /dev/null +++ b/docs/snippets/html/list-story-reuse-data.ts.mdx @@ -0,0 +1,32 @@ + +```ts +// List.stories.ts + +import { Meta, StoryFn } from '@storybook/html'; + +import { createList, ListArgs } from './List'; +import { createListItem } from './ListItem'; + +// 👇 We're importing the necessary stories from ListItem +import { Selected, Unselected } from './ListItem.stories'; + +export default { + title: 'List', +} as Meta; + +export const Empty: StoryFn = (args) => createList(args); + +export const OneItem: StoryFn = (args) => { + const list = createList(args); + list.appendChild(createListItem()); + return list; +}; + +export const ManyItems: StoryFn = (args) => { + const list = createList(args); + list.appendChild(createListItem(Selected.args)); + list.appendChild(createListItem(Unselected.args)); + list.appendChild(createListItem(Unselected.args)); + return list; +}; +``` diff --git a/docs/snippets/html/list-story-starter.js.mdx b/docs/snippets/html/list-story-starter.js.mdx new file mode 100644 index 000000000000..8e4959b468d3 --- /dev/null +++ b/docs/snippets/html/list-story-starter.js.mdx @@ -0,0 +1,12 @@ +```js +// List.stories.js + +import { createList } from './List'; + +export default { + title: 'List', +}; + +// Always an empty list, not super interesting +const Template = (args) => createList(args); +``` diff --git a/docs/snippets/html/list-story-starter.ts.mdx b/docs/snippets/html/list-story-starter.ts.mdx new file mode 100644 index 000000000000..e0706e6c0827 --- /dev/null +++ b/docs/snippets/html/list-story-starter.ts.mdx @@ -0,0 +1,14 @@ +```ts +// List.stories.ts + +import { Meta, StoryFn } from '@storybook/html'; + +import { createList, ListArgs } from './List'; + +export default { + title: 'List', +} as Meta; + +// Always an empty list, not super interesting +const Template: StoryFn = (args) => createList(args); +``` diff --git a/docs/snippets/react/page-story-with-args-composition.ts.mdx b/docs/snippets/react/page-story-with-args-composition.ts.mdx index a088dfda54fe..be960adff652 100644 --- a/docs/snippets/react/page-story-with-args-composition.ts.mdx +++ b/docs/snippets/react/page-story-with-args-composition.ts.mdx @@ -18,7 +18,6 @@ export default { */ title: 'DocumentScreen', component: DocumentScreen, - title: 'DocumentScreen', } as ComponentMeta; @@ -30,4 +29,4 @@ Simple.args = { document: DocumentHeader.Simple.args.document, subdocuments: DocumentList.Simple.args.documents, }; -``` \ No newline at end of file +``` diff --git a/docs/writing-stories/args.md b/docs/writing-stories/args.md index b7b5ac95c273..6d10a8faab72 100644 --- a/docs/writing-stories/args.md +++ b/docs/writing-stories/args.md @@ -33,6 +33,8 @@ To define the args of a single story, use the `args` CSF story key: 'svelte/button-story-with-args.native-format.mdx', 'svelte/button-story-with-args.mdx.mdx', 'web-components/button-story-with-args.js.mdx', + 'html/button-story-with-args.ts.mdx', + 'html/button-story-with-args.js.mdx', ]} /> diff --git a/docs/writing-stories/build-pages-with-storybook.md b/docs/writing-stories/build-pages-with-storybook.md index 9ebd55d0e8e5..9bced0a9b45c 100644 --- a/docs/writing-stories/build-pages-with-storybook.md +++ b/docs/writing-stories/build-pages-with-storybook.md @@ -2,7 +2,7 @@ title: 'Building pages with Storybook' --- -Storybook helps you build any component, from small “atomic” components to composed pages. But as you move up the component hierarchy toward the level of pages, you end up dealing with more complexity. +Storybook helps you build any component, from small “atomic” components to composed pages. But as you move up the component hierarchy toward the page level, you deal with more complexity. There are many ways to build pages in Storybook. Here are common patterns and solutions. @@ -47,7 +47,7 @@ When you are building screens in this way, it is typical that the inputs of a co -In such cases it is natural to use [args composition](./args.md#args-composition) to build the stories for the page based on the stories of the sub-components: +In such cases, it is natural to use [args composition](./args.md#args-composition) to build the stories for the page based on the stories of the sub-components: @@ -72,13 +72,57 @@ If you need to render a connected component in Storybook, you can mock the netwo ### Mocking providers -If you are using a provider that supplies data via the context, you can wrap your story in a decorator that provides a mocked version of that provider. For example, in the [Screens](https://storybook.js.org/tutorials/intro-to-storybook/react/en/screen/) chapter of the Intro to Storybook tutorial, we mock a Redux provider with mock data. +Suppose you are using a provider that supplies data via the context. In that case, you can wrap your story in a decorator that provides a mocked version of that provider. For example, in the [Screens](https://storybook.js.org/tutorials/intro-to-storybook/react/en/screen/) chapter of the Intro to Storybook tutorial, we mock a Redux provider with mock data. ### Mocking API Services -Connected applications such as Twitter, Instagram, amongst others, are everywhere, consuming data either from REST or GraphQL endpoints. If you're working in an application that relies on either of these data providers, you can add Mock Service Worker (MSW) via [Storybook's MSW addon](https://storybook.js.org/addons/msw-storybook-addon) to mock data alongside your app and stories. +Connected applications such as Twitter, Instagram, amongst others, are everywhere, consuming data from REST or GraphQL endpoints. Suppose you're working in an application that relies on either of these data providers. In that case, you can add Mock Service Worker (MSW) via [Storybook's MSW addon](https://storybook.js.org/addons/msw-storybook-addon) to mock data alongside your app and stories. -[Mock Service Worker](https://mswjs.io/) is an API mocking library. It relies on service workers to capture network requests and provides mocked data in response. The MSW addon adds this functionality into Storybook, allowing you to mock API requests in your stories. +[Mock Service Worker](https://mswjs.io/) is an API mocking library. It relies on service workers to capture network requests and provides mocked data in response. The MSW addon adds this functionality into Storybook, allowing you to mock API requests in your stories. Below is an overview of how to set up and use the addon. + +Run the following commands to install MSW, the addon, and generate a mock service worker. + + + + + + + +
+ +💡 If you're working with Angular, you'll need to adjust the command to save the mock service worker file in a different directory (e.g., `src`). + +
+ +Update your `.storybook/preview.js` file and enable the addon via a [global decorator](./decorators.md#global-decorators). + + + + + + + +Finally, update your [`.storybook/main.js|ts`](../configure/overview.md#using-storybook-api) to allow Storybook to load the generated mock service worker file as follows: + + + + + + #### Mocking REST requests with MSW addon @@ -157,7 +201,7 @@ To test your screen with the GraphQL mocked data, you could write the following It is also possible to mock imports directly, as you might in a unit test, using Webpack’s aliasing. It's advantageous if your component makes network requests directly with third-party libraries. -We're going to use [isomorphic-fetch](https://www.npmjs.com/package/isomorphic-fetch) as an example. +We'll use [isomorphic-fetch](https://www.npmjs.com/package/isomorphic-fetch) as an example. Inside a directory called `__mocks__`, create a new file called `isomorphic-fetch.js` with the following code: @@ -223,7 +267,7 @@ Like the [import mocking](##mocking-imports) above, once you have a mock, you’ It's possible to avoid mocking the dependencies of connected "container" components entirely by passing them around via props or React context. However, it requires a strict split of the container and presentational component logic. For example, if you have a component responsible for data fetching logic and rendering DOM, it will need to be mocked as previously described. -It’s common to import and embed container components amongst presentational components. However, as we discovered earlier, to render them within Storybook, we’ll likely have to mock their dependencies or the imports themselves. +It’s common to import and embed container components amongst presentational components. However, as we discovered earlier, we’ll likely have to mock their dependencies or the imports to render them within Storybook. Not only can this quickly grow to become a tedious task, but it’s also challenging to mock container components that use local states. So, instead of importing containers directly, a solution to this problem is to create a React context that provides the container components. It allows you to freely embed container components as usual, at any level in the component hierarchy without worrying about subsequently mocking their dependencies; since we can swap out the containers themselves with their mocked presentational counterpart. @@ -238,7 +282,7 @@ ProfilePageContext.js
-It’s also often helpful to set up a “global” container context (perhaps named `GlobalContainerContext`) for container components that may be rendered on every page of your app and adding them to the top level of your application. While it’s possible to place every container within this global context, it should only provide globally required containers. +It’s also often helpful to set up a “global” container context (perhaps named `GlobalContainerContext`) for container components that may be rendered on every page of your app and add them to the top level of your application. While it’s possible to place every container within this global context, it should only provide globally required containers.
@@ -284,7 +328,7 @@ In the context of Storybook, instead of providing container components through c
-If the same context applies to all `ProfilePage` stories, we can also use a [decorator](./decorators.md). +If the same context applies to all `ProfilePage` stories, we can use a [decorator](./decorators.md).
diff --git a/docs/writing-stories/introduction.md b/docs/writing-stories/introduction.md index 96ca9925fffa..15e4c456516b 100644 --- a/docs/writing-stories/introduction.md +++ b/docs/writing-stories/introduction.md @@ -37,6 +37,8 @@ The _default_ export metadata controls how Storybook lists your stories and prov 'angular/button-story-default-export-with-component.ts.mdx', 'svelte/button-story-default-export-with-component.js.mdx', 'web-components/button-story-default-export-with-component.js.mdx', + 'html/button-story-default-export.js.mdx', + 'html/button-story-default-export.ts.mdx', ]} /> @@ -59,6 +61,8 @@ Use the _named_ exports of a CSF file to define your component’s stories. We r 'svelte/button-story.js.mdx', 'svelte/button-story.native-format.mdx', 'web-components/button-story.js.mdx', + 'html/button-story.js.mdx', + 'html/button-story.ts.mdx', ]} /> @@ -99,6 +103,8 @@ You can rename any particular story you need. For instance, to give it a more ac 'angular/button-story-rename-story.ts.mdx', 'svelte/button-story-rename-story.js.mdx', 'web-components/button-story-rename-story.js.mdx', + 'html/button-story-rename-story.js.mdx', + 'html/button-story-rename-story.ts.mdx', ]} /> @@ -127,6 +133,8 @@ A story is a function that describes how to render a component. You can have mul 'svelte/button-story-with-emojis.native-format.mdx', 'svelte/button-story-with-emojis.mdx.mdx', 'web-components/button-story-with-emojis.js.mdx', + 'html/button-story-with-emojis.js.mdx', + 'html/button-story-with-emojis.ts.mdx', ]} /> @@ -152,6 +160,8 @@ Refine this pattern by introducing `args` for your component's stories. It reduc 'svelte/button-story-using-args.js.mdx', 'svelte/button-story-using-args.native-format.mdx', 'web-components/button-story-using-args.js.mdx', + 'html/button-story-using-args.js.mdx', + 'html/button-story-using-args.ts.mdx', ]} /> @@ -254,6 +264,8 @@ For instance, suppose you wanted to test your Button component against a differe 'svelte/button-story-with-blue-args.native-format.mdx', 'svelte/button-story-with-blue-args.mdx.mdx', 'web-components/button-story-with-blue-args.js.mdx', + 'html/button-story-with-blue-args.js.mdx', + 'html/button-story-with-blue-args.ts.mdx', ]} /> @@ -286,6 +298,8 @@ A simple example is adding padding to a component’s stories. Accomplish this u 'svelte/button-story-component-decorator.native-format.mdx', 'svelte/button-story-component-decorator.mdx.mdx', 'web-components/button-story-component-decorator.js.mdx', + 'html/button-story-component-decorator.js.mdx', + 'html/button-story-component-decorator.ts.mdx', ]} /> @@ -310,6 +324,8 @@ When building design systems or component libraries, you may have two or more co 'vue/list-story-starter.ts-3.ts.mdx', 'svelte/list-story-starter.native-format.mdx', 'web-components/list-story-starter.js.mdx', + 'html/list-story-starter.js.mdx', + 'html/list-story-starter.ts.mdx', ]} /> @@ -330,6 +346,8 @@ In such cases, it makes sense to render a different function for each story: 'vue/list-story-expanded.ts-3.ts.mdx', 'svelte/list-story-expanded.native-format.mdx', 'web-components/list-story-expanded.js.mdx', + 'html/list-story-expanded.js.mdx', + 'html/list-story-expanded.ts.mdx', ]} /> @@ -349,6 +367,8 @@ You can also reuse stories from the child `ListItem` in your `List` component. T 'vue/list-story-reuse-data.3.js.mdx', 'vue/list-story-reuse-data.ts-3.ts.mdx', 'web-components/list-story-reuse-data.js.mdx', + 'html/list-story-reuse-data.js.mdx', + 'html/list-story-reuse-data.ts.mdx', ]} /> diff --git a/docs/writing-stories/play-function.md b/docs/writing-stories/play-function.md index cef5c1be9920..0923ee57a2c3 100644 --- a/docs/writing-stories/play-function.md +++ b/docs/writing-stories/play-function.md @@ -10,13 +10,16 @@ We recommend installing Storybook's [`addon-interactions`](https://storybook.js. Run the following command to install the addon and the required dependencies. -```shell -# With npm -npm install @storybook/addon-interactions @storybook/testing-library --save-dev + -# With yarn -yarn add --dev @storybook/addon-interactions @storybook/testing-library -``` + + + Update your Storybook configuration (in `.storybook/main.js`) to include the interactions addon. diff --git a/docs/writing-tests/interaction-testing.md b/docs/writing-tests/interaction-testing.md index 1b86c56dfc01..d4d74ea0ca48 100644 --- a/docs/writing-tests/interaction-testing.md +++ b/docs/writing-tests/interaction-testing.md @@ -157,7 +157,7 @@ Interaction tests can be expensive to maintain when applied wholesale to every c - [Test runner](./test-runner.md) to automate test execution - [Visual tests](./visual-testing.md) for appearance -- [Accessibility tests](accessibility-testing.md) for accessibility +- [Accessibility tests](./accessibility-testing.md) for accessibility - Interaction tests for user behavior simulation - [Snapshot tests](./snapshot-testing.md) for rendering errors and warnings -- [Import stories in other tests](./importing-stories-in-tests.md) for other tools \ No newline at end of file +- [Import stories in other tests](./importing-stories-in-tests.md) for other tools diff --git a/docs/writing-tests/snapshot-testing.md b/docs/writing-tests/snapshot-testing.md index 242c1f00885f..1b90a05dfec7 100644 --- a/docs/writing-tests/snapshot-testing.md +++ b/docs/writing-tests/snapshot-testing.md @@ -14,13 +14,16 @@ Storybook is a helpful tool for snapshot testing because every story is essentia Run the following command to install Storyshots: -```shell -# With npm -npm install @storybook/addon-storyshots --save-dev + -# With yarn -yarn add --dev @storybook/addon-storyshots -``` + + + Add a test file to your environment with the following contents to configure Storyshots: diff --git a/docs/writing-tests/test-runner.md b/docs/writing-tests/test-runner.md index 5502adfbcd15..e72bd8205454 100644 --- a/docs/writing-tests/test-runner.md +++ b/docs/writing-tests/test-runner.md @@ -43,8 +43,8 @@ Start your Storybook with: @@ -302,4 +302,4 @@ As the test runner is based on Playwright, you might need to use specific docker - [Accessibility tests](./accessibility-testing.md) for accessibility - [Interaction tests](./interaction-testing.md) for user behavior simulation - [Snapshot tests](./snapshot-testing.md) for rendering errors and warnings -- [Import stories in other tests](./importing-stories-in-tests.md) for other tools \ No newline at end of file +- [Import stories in other tests](./importing-stories-in-tests.md) for other tools diff --git a/docs/writing-tests/visual-testing.md b/docs/writing-tests/visual-testing.md index a5336a3854a0..bed00fbfcffb 100644 --- a/docs/writing-tests/visual-testing.md +++ b/docs/writing-tests/visual-testing.md @@ -20,13 +20,18 @@ To get started, sign up with your [GitHub](https://github.com/), [GitLab](https: Next, install the [chromatic](https://www.npmjs.com/package/chromatic) CLI package from npm: -```shell -# With npm -npm install chromatic --save-dev + + + + + + -# With yarn -yarn add --dev chromatic -``` Run the following command after the package finishes installing: diff --git a/examples/angular-cli/package.json b/examples/angular-cli/package.json index cf04964c67aa..a4144d29e1bb 100644 --- a/examples/angular-cli/package.json +++ b/examples/angular-cli/package.json @@ -54,7 +54,7 @@ "@storybook/babel-plugin-require-context-hook": "1.0.1", "@storybook/jest": "^0.0.5", "@storybook/source-loader": "6.5.0-rc.1", - "@storybook/testing-library": "^0.0.7", + "@storybook/testing-library": "0.0.14-next.0", "@types/core-js": "^2.5.4", "@types/jest": "^26.0.16", "@types/node": "^14.14.20 || ^16.0.0", diff --git a/examples/official-storybook/package.json b/examples/official-storybook/package.json index 1bd706b5591d..35f2cb44eb4d 100644 --- a/examples/official-storybook/package.json +++ b/examples/official-storybook/package.json @@ -36,7 +36,7 @@ "@storybook/react": "6.5.0-rc.1", "@storybook/router": "6.5.0-rc.1", "@storybook/source-loader": "6.5.0-rc.1", - "@storybook/testing-library": "^0.0.7", + "@storybook/testing-library": "0.0.14-next.0", "@storybook/theming": "6.5.0-rc.1", "@testing-library/dom": "^7.31.2", "@testing-library/user-event": "^13.1.9", diff --git a/examples/react-ts/.storybook/main.ts b/examples/react-ts/.storybook/main.ts index 752f85c6ac60..33fb89ce230f 100644 --- a/examples/react-ts/.storybook/main.ts +++ b/examples/react-ts/.storybook/main.ts @@ -37,7 +37,7 @@ const config: StorybookConfig = { }, features: { postcss: false, - // modernInlineRender: true, + modernInlineRender: true, storyStoreV7: !global.navigator?.userAgent?.match?.('jsdom'), buildStoriesJson: true, babelModeV7: true, diff --git a/examples/react-ts/src/__snapshots__/storyshots.test.ts.snap b/examples/react-ts/src/__snapshots__/storyshots.test.ts.snap index 409f2a8ab57e..a3430706744a 100644 --- a/examples/react-ts/src/__snapshots__/storyshots.test.ts.snap +++ b/examples/react-ts/src/__snapshots__/storyshots.test.ts.snap @@ -4041,6 +4041,51 @@ exports[`Storyshots Demo/Examples / Emoji Button With Args 1`] = ` `; +exports[`Storyshots Demo/button2 One 1`] = ` + +`; + +exports[`Storyshots Demo/button2 Three 1`] = ` + +`; + +exports[`Storyshots Demo/button2 Two 1`] = ` + +`; + +exports[`Storyshots Demo/button3 Five 1`] = ` + +`; + +exports[`Storyshots Demo/button3 Four 1`] = ` + +`; + exports[`Storyshots Docs/ButtonMdx Basic 1`] = ` -); +export const Button = ({ label = 'Hello', icon: Icon, ...props }: ButtonProps) => { + useEffect(() => { + const fn = () => console.log(`click ${label}`); + global.window.document.querySelector('body')?.addEventListener('click', fn); + return () => global.window.document.querySelector('body')?.removeEventListener('click', fn); + }); + return ( + + ); +}; diff --git a/examples/react-ts/src/button2.stories.tsx b/examples/react-ts/src/button2.stories.tsx new file mode 100644 index 000000000000..cfaa6df924d4 --- /dev/null +++ b/examples/react-ts/src/button2.stories.tsx @@ -0,0 +1,10 @@ +import { Button } from './button'; + +export default { + component: Button, + title: 'button2', +}; + +export const one = { args: { label: 'one' } }; +export const two = { args: { label: 'two' } }; +export const three = { args: { label: 'three' } }; diff --git a/examples/react-ts/src/button3.stories.tsx b/examples/react-ts/src/button3.stories.tsx new file mode 100644 index 000000000000..941d8f436f3b --- /dev/null +++ b/examples/react-ts/src/button3.stories.tsx @@ -0,0 +1,9 @@ +import { Button } from './button'; + +export default { + component: Button, + title: 'button3', +}; + +export const four = { args: { label: 'four' } }; +export const five = { args: { label: 'five' } }; diff --git a/examples/svelte-kitchen-sink/package.json b/examples/svelte-kitchen-sink/package.json index 881a8306072f..9d6edc94512f 100644 --- a/examples/svelte-kitchen-sink/package.json +++ b/examples/svelte-kitchen-sink/package.json @@ -24,7 +24,7 @@ "@storybook/jest": "^0.0.5", "@storybook/source-loader": "6.5.0-rc.1", "@storybook/svelte": "6.5.0-rc.1", - "@storybook/testing-library": "^0.0.7", + "@storybook/testing-library": "0.0.14-next.0", "svelte-jester": "1.3.0", "svelte-preprocess": "4.6.8" }, diff --git a/examples/vue-3-cli/.storybook/main.js b/examples/vue-3-cli/.storybook/main.js index 5858049fd74c..0699c40dfc40 100644 --- a/examples/vue-3-cli/.storybook/main.js +++ b/examples/vue-3-cli/.storybook/main.js @@ -10,6 +10,7 @@ module.exports = { disableTelemetry: true, }, features: { + storyStoreV7: !global.navigator?.userAgent?.match?.('jsdom'), buildStoriesJson: true, channelOptions: { allowFunction: false, maxDepth: 10 }, }, diff --git a/examples/vue-3-cli/package.json b/examples/vue-3-cli/package.json index f2f4f3481380..f87414b6d097 100644 --- a/examples/vue-3-cli/package.json +++ b/examples/vue-3-cli/package.json @@ -20,7 +20,7 @@ "@storybook/addon-links": "6.5.0-rc.1", "@storybook/addon-storyshots": "6.5.0-rc.1", "@storybook/jest": "^0.0.5", - "@storybook/testing-library": "^0.0.7", + "@storybook/testing-library": "0.0.14-next.0", "@storybook/vue3": "6.5.0-rc.1", "@vue/cli-plugin-babel": "~4.5.0", "@vue/cli-plugin-typescript": "~4.5.0", diff --git a/examples/vue-cli/.storybook/main.js b/examples/vue-cli/.storybook/main.js index 742a7b1d5ab4..e80616cd0d8f 100644 --- a/examples/vue-cli/.storybook/main.js +++ b/examples/vue-cli/.storybook/main.js @@ -13,6 +13,7 @@ module.exports = { disableTelemetry: true, }, features: { + storyStoreV7: true, buildStoriesJson: true, }, }; diff --git a/examples/vue-kitchen-sink/.storybook/main.js b/examples/vue-kitchen-sink/.storybook/main.js index eb7979f07f20..6068e3c04089 100644 --- a/examples/vue-kitchen-sink/.storybook/main.js +++ b/examples/vue-kitchen-sink/.storybook/main.js @@ -20,5 +20,6 @@ module.exports = { staticDirs: ['../public'], features: { buildStoriesJson: true, + storyStoreV7: !global.navigator?.userAgent?.match?.('jsdom'), }, }; diff --git a/examples/vue-kitchen-sink/.storybook/preview.js b/examples/vue-kitchen-sink/.storybook/preview.js index 65ca5b85929d..9f879a2bad57 100644 --- a/examples/vue-kitchen-sink/.storybook/preview.js +++ b/examples/vue-kitchen-sink/.storybook/preview.js @@ -10,4 +10,5 @@ export const parameters = { docs: { iframeHeight: '60px', }, + globalParameter: 'globalParameter', }; diff --git a/examples/vue-kitchen-sink/package.json b/examples/vue-kitchen-sink/package.json index 29d40181469a..042c6c94925d 100644 --- a/examples/vue-kitchen-sink/package.json +++ b/examples/vue-kitchen-sink/package.json @@ -27,7 +27,7 @@ "@storybook/addons": "6.5.0-rc.1", "@storybook/jest": "^0.0.5", "@storybook/source-loader": "6.5.0-rc.1", - "@storybook/testing-library": "^0.0.7", + "@storybook/testing-library": "0.0.14-next.0", "@storybook/vue": "6.5.0-rc.1", "@vue/babel-preset-jsx": "^1.2.4", "babel-loader": "^8.0.0", diff --git a/examples/vue-kitchen-sink/src/App.vue b/examples/vue-kitchen-sink/src/App.vue index 06f14e40a8ca..7695b522c011 100644 --- a/examples/vue-kitchen-sink/src/App.vue +++ b/examples/vue-kitchen-sink/src/App.vue @@ -30,7 +30,7 @@ export default { } -