diff --git a/code/e2e-tests/addon-docs.spec.ts b/code/e2e-tests/addon-docs.spec.ts index 1e50e4433794..f3f5f9edbf10 100644 --- a/code/e2e-tests/addon-docs.spec.ts +++ b/code/e2e-tests/addon-docs.spec.ts @@ -60,10 +60,11 @@ test.describe('addon-docs', () => { // The `` block should render the "Basic" story, and the `` block should // render both the "Basic" and "Another" story const root = sbPage.previewRoot(); - const stories = root.locator('.sbdocs-h3'); + const stories = root.locator('.sb-story button'); - await expect(await stories.count()).toBe(2); + await expect(await stories.count()).toBe(3); await expect(stories.first()).toHaveText('Basic'); + await expect(stories.nth(1)).toHaveText('Basic'); await expect(stories.last()).toHaveText('Another'); }); }); diff --git a/code/frameworks/sveltekit/README.md b/code/frameworks/sveltekit/README.md index 7c69390208df..e02a1c5a9123 100644 --- a/code/frameworks/sveltekit/README.md +++ b/code/frameworks/sveltekit/README.md @@ -23,20 +23,20 @@ Check out our [Frameworks API](https://storybook.js.org/blog/framework-api/) ann All Svelte language features are supported out of the box, as Storybook uses the Svelte compiler underneath. However SvelteKit has some [Kit-specific modules](https://kit.svelte.dev/docs/modules) that currently aren't supported. It's on our roadmap to support most of them soon: -| **Module** | **Status** | **Note** | -| ---------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------- | -| [`$app/environment`](https://kit.svelte.dev/docs/modules#$app-environment) | ✅ Supported | `version` is always empty in Storybook. | -| [`$app/forms`](https://kit.svelte.dev/docs/modules#$app-forms) | ⏳ Planned for 7.1 | See [section in Troubleshooting](#error-cannot-read-properties-of-undefined-reading-disable_scroll_handling-in-preview). `applyAction` depends on the client singleton having been initialized in SvelteKit's `singletons.js`. | +| **Module** | **Status** | **Note** | +| ---------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| [`$app/environment`](https://kit.svelte.dev/docs/modules#$app-environment) | ✅ Supported | `version` is always empty in Storybook. | +| [`$app/forms`](https://kit.svelte.dev/docs/modules#$app-forms) | ⏳ Planned for 7.1 | See [section in Troubleshooting](#error-cannot-read-properties-of-undefined-reading-disable_scroll_handling-in-preview). `applyAction` depends on the client singleton having been initialized in SvelteKit's `singletons.js`. | | [`$app/navigation`](https://kit.svelte.dev/docs/modules#$app-navigation) | ⏳ Planned for 7.1. With mocks so the Actions addon will display when the hooks are being called. | See [section in Troubleshooting](#error-cannot-read-properties-of-undefined-reading-disable_scroll_handling-in-preview). `$app/navigation` depends on the client singleton having been initialized in SvelteKit's `singletons.js`. | -| [`$app/paths`](https://kit.svelte.dev/docs/modules#$app-paths) | ⏳ Planned for 7.1. | These are global variables set in SvelteKit's `runtime/shared.js` | -| [`$app/stores`](https://kit.svelte.dev/docs/modules#$app-stores) | ✅ Supported | Mocks planned for 7.1, so you can set different store values per story. | -| [`$env/dynamic/private`](https://kit.svelte.dev/docs/modules#$env-dynamic-private) | ⛔ Not supported | They are meant to only be available server-side, and Storybook renders all components on the client. | -| [`$env/dynamic/public`](https://kit.svelte.dev/docs/modules#$env-dynamic-public) | 🚧 Partially supported | Only supported in development mode. | -| [`$env/static/private`](https://kit.svelte.dev/docs/modules#$env-static-private) | ⛔ Not supported | They are meant to only be available server-side, and Storybook renders all components on the client. | -| [`$env/static/public`](https://kit.svelte.dev/docs/modules#$env-static-public) | ✅ Supported | | -| [`$lib`](https://kit.svelte.dev/docs/modules#$lib) | ✅ Supported | | -| [`$service-worker`](https://kit.svelte.dev/docs/modules#$service-worker) | ⛔ Not supported | They are only meant to be used in service workers | -| [`@sveltejs/kit/*`](https://kit.svelte.dev/docs/modules#sveltejs-kit) | ✅ Supported | | +| [`$app/paths`](https://kit.svelte.dev/docs/modules#$app-paths) | ⏳ Planned for 7.1. | These are global variables set in SvelteKit's `runtime/shared.js` | +| [`$app/stores`](https://kit.svelte.dev/docs/modules#$app-stores) | ✅ Supported | Mocks planned for 7.1, so you can set different store values per story. | +| [`$env/dynamic/private`](https://kit.svelte.dev/docs/modules#$env-dynamic-private) | ⛔ Not supported | They are meant to only be available server-side, and Storybook renders all components on the client. | +| [`$env/dynamic/public`](https://kit.svelte.dev/docs/modules#$env-dynamic-public) | 🚧 Partially supported | Only supported in development mode. | +| [`$env/static/private`](https://kit.svelte.dev/docs/modules#$env-static-private) | ⛔ Not supported | They are meant to only be available server-side, and Storybook renders all components on the client. | +| [`$env/static/public`](https://kit.svelte.dev/docs/modules#$env-static-public) | ✅ Supported | | +| [`$lib`](https://kit.svelte.dev/docs/modules#$lib) | ✅ Supported | | +| [`$service-worker`](https://kit.svelte.dev/docs/modules#$service-worker) | ⛔ Not supported | They are only meant to be used in service workers | +| [`@sveltejs/kit/*`](https://kit.svelte.dev/docs/modules#sveltejs-kit) | ✅ Supported | | This is just the beginning. We're close to adding basic support for many of the SvelteKit features. Longer term we're planning on making it an even better experience to [build](https://storybook.js.org/docs/7.0/react/writing-stories/introduction), [test](https://storybook.js.org/docs/7.0/react/writing-tests/introduction) and [document](https://storybook.js.org/docs/7.0/react/writing-docs/introduction) all the SvelteKit goodies like [pages](https://kit.svelte.dev/docs/routing), [forms](https://kit.svelte.dev/docs/form-actions) and [layouts](https://kit.svelte.dev/docs/routing#layout) in Storybook, while still integrating with all the addons and workflows you know and love. diff --git a/code/ui/blocks/src/blocks/Anchor.stories.tsx b/code/ui/blocks/src/blocks/Anchor.stories.tsx index 41e7e9da3046..bc940993573e 100644 --- a/code/ui/blocks/src/blocks/Anchor.stories.tsx +++ b/code/ui/blocks/src/blocks/Anchor.stories.tsx @@ -3,6 +3,9 @@ import { Anchor } from './Anchor'; const meta = { component: Anchor, + parameters: { + docsStyles: true, + }, } as Meta; export default meta; diff --git a/code/ui/blocks/src/blocks/ArgTypes.stories.tsx b/code/ui/blocks/src/blocks/ArgTypes.stories.tsx index 5248a56a8e3c..5176d59621bb 100644 --- a/code/ui/blocks/src/blocks/ArgTypes.stories.tsx +++ b/code/ui/blocks/src/blocks/ArgTypes.stories.tsx @@ -8,6 +8,7 @@ const meta: Meta = { component: ArgTypes, parameters: { relativeCsfPaths: ['../examples/ArgTypesParameters.stories'], + docsStyles: true, }, }; export default meta; diff --git a/code/ui/blocks/src/blocks/Canvas.stories.tsx b/code/ui/blocks/src/blocks/Canvas.stories.tsx index ccc50895e53c..2fedb7e97b5e 100644 --- a/code/ui/blocks/src/blocks/Canvas.stories.tsx +++ b/code/ui/blocks/src/blocks/Canvas.stories.tsx @@ -25,6 +25,7 @@ const meta: Meta = { />`, }, }, + docsStyles: true, }, decorators: SourceStoriesMeta.decorators, }; diff --git a/code/ui/blocks/src/blocks/Controls.stories.tsx b/code/ui/blocks/src/blocks/Controls.stories.tsx index ff8b6e9409aa..d8da8fabb0bd 100644 --- a/code/ui/blocks/src/blocks/Controls.stories.tsx +++ b/code/ui/blocks/src/blocks/Controls.stories.tsx @@ -7,6 +7,7 @@ const meta: Meta = { component: Controls, parameters: { relativeCsfPaths: ['../examples/ControlsParameters.stories'], + docsStyles: true, }, }; export default meta; diff --git a/code/ui/blocks/src/blocks/Description.stories.tsx b/code/ui/blocks/src/blocks/Description.stories.tsx index 29c743561221..0e940c37cf54 100644 --- a/code/ui/blocks/src/blocks/Description.stories.tsx +++ b/code/ui/blocks/src/blocks/Description.stories.tsx @@ -16,6 +16,7 @@ const meta: Meta = { // workaround for https://github.com/storybookjs/storybook/issues/20505 docs: { source: { type: 'code' } }, attached: false, + docsStyles: true, }, }; export default meta; diff --git a/code/ui/blocks/src/blocks/DocsStory.tsx b/code/ui/blocks/src/blocks/DocsStory.tsx index 1c9599667acc..70960447402f 100644 --- a/code/ui/blocks/src/blocks/DocsStory.tsx +++ b/code/ui/blocks/src/blocks/DocsStory.tsx @@ -10,12 +10,15 @@ import { useOf } from './useOf'; export const DocsStory: FC = ({ of, expanded = true, - withToolbar = false, + withToolbar: withToolbarProp = false, __forceInitialArgs = false, __primary = false, }) => { const { story } = useOf(of || 'story', ['story']); + // use withToolbar from parameters or default to true in autodocs + const withToolbar = story.parameters.docs?.canvas?.withToolbar ?? withToolbarProp; + return ( {expanded && ( diff --git a/code/ui/blocks/src/blocks/Markdown.stories.tsx b/code/ui/blocks/src/blocks/Markdown.stories.tsx index 5d12484fa806..13d7b0e707a8 100644 --- a/code/ui/blocks/src/blocks/Markdown.stories.tsx +++ b/code/ui/blocks/src/blocks/Markdown.stories.tsx @@ -5,6 +5,7 @@ import mdContent from '../examples/Markdown-content.md?raw'; export default { component: MarkdownComponent, + parameters: { docsStyles: true }, }; export const Markdown = { diff --git a/code/ui/blocks/src/blocks/Primary.stories.tsx b/code/ui/blocks/src/blocks/Primary.stories.tsx new file mode 100644 index 000000000000..42977ff6c9e3 --- /dev/null +++ b/code/ui/blocks/src/blocks/Primary.stories.tsx @@ -0,0 +1,24 @@ +import type { Meta, StoryObj } from '@storybook/react'; +import { Primary } from './Primary'; + +const meta = { + component: Primary, + parameters: { + docsStyles: true, + }, +} satisfies Meta; + +export default meta; + +type Story = StoryObj; + +export const Default: Story = { + parameters: { + relativeCsfPaths: ['../examples/Button.stories'], + }, +}; +export const WithoutToolbar: Story = { + parameters: { + relativeCsfPaths: ['../examples/StoriesParameters.stories'], + }, +}; diff --git a/code/ui/blocks/src/blocks/Primary.tsx b/code/ui/blocks/src/blocks/Primary.tsx index 1a4e36672453..7583200f72c8 100644 --- a/code/ui/blocks/src/blocks/Primary.tsx +++ b/code/ui/blocks/src/blocks/Primary.tsx @@ -23,6 +23,6 @@ export const Primary: FC = ({ name }) => { const storyId = name && docsContext.storyIdByName(name); const story = docsContext.storyById(storyId); return story ? ( - + ) : null; }; diff --git a/code/ui/blocks/src/blocks/Source.stories.tsx b/code/ui/blocks/src/blocks/Source.stories.tsx index 00a9ea2d3741..d9bd1d747b52 100644 --- a/code/ui/blocks/src/blocks/Source.stories.tsx +++ b/code/ui/blocks/src/blocks/Source.stories.tsx @@ -18,6 +18,7 @@ const meta: Meta = { code: `const emitted = 'source';`, }, }, + docsStyles: true, }, decorators: [ (Story, { parameters: { snippets = {} } }) => ( @@ -83,6 +84,10 @@ export const CodeUnattached: Story = { parameters: { attached: false }, }; +export const EmptyUnattached: Story = { + parameters: { attached: false }, +}; + export const CodeParameters: Story = { args: { of: ParametersStories.Code }, }; diff --git a/code/ui/blocks/src/blocks/Source.tsx b/code/ui/blocks/src/blocks/Source.tsx index 4957ad5aa55b..9ca2f0230dbc 100644 --- a/code/ui/blocks/src/blocks/Source.tsx +++ b/code/ui/blocks/src/blocks/Source.tsx @@ -118,8 +118,7 @@ export const useSourceProps = ( // Always fall back to the primary story for source parameters, even if code is set. stories = [docsContext.storyById()]; } catch (err) { - // You are allowed to use unattached. - if (!props.code) throw err; + // You are allowed to use and unattached. } } diff --git a/code/ui/blocks/src/blocks/Stories.stories.tsx b/code/ui/blocks/src/blocks/Stories.stories.tsx new file mode 100644 index 000000000000..9462f5f2a2dd --- /dev/null +++ b/code/ui/blocks/src/blocks/Stories.stories.tsx @@ -0,0 +1,28 @@ +import type { Meta, StoryObj } from '@storybook/react'; +import { Stories } from './Stories'; + +const meta = { + component: Stories, + parameters: { docsStyles: true }, +} satisfies Meta; + +export default meta; + +type Story = StoryObj; + +export const Default: Story = { + parameters: { + relativeCsfPaths: ['../examples/Button.stories'], + }, +}; +export const WithoutPrimary: Story = { + args: { includePrimary: false }, + parameters: { + relativeCsfPaths: ['../examples/Button.stories'], + }, +}; +export const DifferentToolbars: Story = { + parameters: { + relativeCsfPaths: ['../examples/StoriesParameters.stories'], + }, +}; diff --git a/code/ui/blocks/src/blocks/Story.stories.tsx b/code/ui/blocks/src/blocks/Story.stories.tsx index e2603bc170cd..d41017be55af 100644 --- a/code/ui/blocks/src/blocks/Story.stories.tsx +++ b/code/ui/blocks/src/blocks/Story.stories.tsx @@ -9,6 +9,7 @@ const meta: Meta = { component: StoryBlock, parameters: { relativeCsfPaths: ['../examples/Button.stories', '../examples/StoryParameters.stories'], + docsStyles: true, }, }; export default meta; diff --git a/code/ui/blocks/src/blocks/Unstyled.mdx b/code/ui/blocks/src/blocks/Unstyled.mdx index 4e66f71287b3..c50246fd7918 100644 --- a/code/ui/blocks/src/blocks/Unstyled.mdx +++ b/code/ui/blocks/src/blocks/Unstyled.mdx @@ -8,11 +8,19 @@ However sometimes you might want some of your content to not have these styles a ```md import { Unstyled } from '@storybook/blocks'; +# This heading will be styled + +

So will this subheading

+ > This block quote will be styled ... and so will this paragraph. + # This heading will not be styled + +

Neither will this subheading

+ > This block quote will not be styled ... neither will this paragraph, nor the following component: @@ -22,11 +30,19 @@ import { Unstyled } from '@storybook/blocks'; Yields: +# This heading will be styled + +

So will this subheading

+ > This block quote will be styled ... and so will this paragraph. + # This heading will not be styled + +

Neither will this subheading

+ > This block quote will not be styled ... neither will this paragraph, nor the following component: diff --git a/code/ui/blocks/src/blocks/internal/InternalCanvas.stories.tsx b/code/ui/blocks/src/blocks/internal/InternalCanvas.stories.tsx index c34fe085bc36..fb0f444720c3 100644 --- a/code/ui/blocks/src/blocks/internal/InternalCanvas.stories.tsx +++ b/code/ui/blocks/src/blocks/internal/InternalCanvas.stories.tsx @@ -14,6 +14,7 @@ const meta: Meta = { parameters: { theme: 'light', relativeCsfPaths: ['../examples/Button.stories', '../examples/CanvasParameters.stories'], + docsStyles: true, }, render: (args) => { return ( @@ -50,6 +51,23 @@ export const BasicStoryChildUnattached: Story = { parameters: { attached: false }, }; +export const NoStoryChildrenUnattached: Story = { + parameters: { attached: false }, + render: (args) => { + return ( + +

This is a plain paragraph, no stories

+
+ ); + }, +}; +export const NoStoryChildrenUnattachedWithMDXSource: Story = { + ...NoStoryChildrenUnattached, + args: { + mdxSource: `const customStaticSource = true;`, + }, +}; + export const WithSourceOpen: Story = { args: { withSource: SourceState.OPEN, diff --git a/code/ui/blocks/src/blocks/internal/InternalDescription.stories.tsx b/code/ui/blocks/src/blocks/internal/InternalDescription.stories.tsx index 2e164aff0012..da4c87728947 100644 --- a/code/ui/blocks/src/blocks/internal/InternalDescription.stories.tsx +++ b/code/ui/blocks/src/blocks/internal/InternalDescription.stories.tsx @@ -7,6 +7,7 @@ const meta: Meta = { component: Description, parameters: { relativeCsfPaths: ['../examples/Button.stories'], + docsStyles: true, }, args: { of: Button, diff --git a/code/ui/blocks/src/blocks/internal/InternalSource.stories.tsx b/code/ui/blocks/src/blocks/internal/InternalSource.stories.tsx index 0c6c7e7926b3..618507195e47 100644 --- a/code/ui/blocks/src/blocks/internal/InternalSource.stories.tsx +++ b/code/ui/blocks/src/blocks/internal/InternalSource.stories.tsx @@ -7,6 +7,7 @@ const meta: Meta = { parameters: { relativeCsfPaths: ['../examples/Button.stories'], attached: false, + docsStyles: true, }, }; diff --git a/code/ui/blocks/src/blocks/internal/InternalStory.stories.tsx b/code/ui/blocks/src/blocks/internal/InternalStory.stories.tsx index e3352c25b636..dc13391aa8d2 100644 --- a/code/ui/blocks/src/blocks/internal/InternalStory.stories.tsx +++ b/code/ui/blocks/src/blocks/internal/InternalStory.stories.tsx @@ -8,6 +8,7 @@ const meta: Meta = { component: StoryBlock, parameters: { relativeCsfPaths: ['../examples/Button.stories'], + docsStyles: true, }, }; export default meta; diff --git a/code/ui/blocks/src/blocks/mdx.tsx b/code/ui/blocks/src/blocks/mdx.tsx index 1f62dab2bc1a..2870b543b7c8 100644 --- a/code/ui/blocks/src/blocks/mdx.tsx +++ b/code/ui/blocks/src/blocks/mdx.tsx @@ -1,7 +1,7 @@ import type { FC, SyntheticEvent } from 'react'; import React, { useContext } from 'react'; import { NAVIGATE_URL } from '@storybook/core-events'; -import { Code, components } from '@storybook/components'; +import { Code, components, nameSpaceClassNames } from '@storybook/components'; import { global } from '@storybook/global'; import { styled } from '@storybook/theming'; import { Source } from '../components'; @@ -120,13 +120,12 @@ export const AnchorMdx: FC = (props) => { return ; }; -const SUPPORTED_MDX_HEADERS = ['h1', 'h2', 'h3', 'h4', 'h5', 'h6']; +const SUPPORTED_MDX_HEADERS = ['h1', 'h2', 'h3', 'h4', 'h5', 'h6'] as const; const OcticonHeaders = SUPPORTED_MDX_HEADERS.reduce( (acc, headerType) => ({ ...acc, - // @ts-expect-error (Converted from ts-ignore) - [headerType]: styled(components[headerType])({ + [headerType]: styled(headerType)({ '& svg': { visibility: 'hidden', }, @@ -213,12 +212,10 @@ export const HeaderMdx: FC = (props) => { ); } - - // @ts-expect-error (Converted from ts-ignore) - const Header = components[as]; - // Make sure it still work if "remark-slug" plugin is not present. - return
; + const Component = as as React.ElementType; + const { as: omittedAs, ...withoutAs } = props; + return ; }; export const HeadersMdx = SUPPORTED_MDX_HEADERS.reduce( diff --git a/code/ui/blocks/src/components/DocsPage.tsx b/code/ui/blocks/src/components/DocsPage.tsx index e81b1da2f9e0..f4d9c72a2881 100644 --- a/code/ui/blocks/src/components/DocsPage.tsx +++ b/code/ui/blocks/src/components/DocsPage.tsx @@ -70,6 +70,7 @@ export const Subtitle = styled.h2(withReset, ({ theme }) => ({ color: transparentize(0.25, theme.color.defaultText), })); +// @ts-expect-error don't know why it doesn't accept our returned styles. if we add `...{}` anywhere to the returned object it stops erroring export const DocsContent = styled.div(({ theme }) => { const reset = { fontFamily: theme.typography.fonts.base, @@ -121,8 +122,6 @@ export const DocsContent = styled.div(({ theme }) => { return { maxWidth: 1000, width: '100%', - - ...reset, [toGlobalSelector('a')]: { ...reset, fontSize: 'inherit', diff --git a/code/ui/blocks/src/examples/StoriesParameters.stories.tsx b/code/ui/blocks/src/examples/StoriesParameters.stories.tsx new file mode 100644 index 000000000000..731291ad75f7 --- /dev/null +++ b/code/ui/blocks/src/examples/StoriesParameters.stories.tsx @@ -0,0 +1,20 @@ +import type { Meta, StoryObj } from '@storybook/react'; + +import { EmptyExample } from './EmptyExample'; + +const meta = { + title: 'examples/Stories for the Stories and Primary Block', + component: EmptyExample, +} satisfies Meta; +export default meta; + +type Story = StoryObj; + +export const WithoutToolbar: Story = { + parameters: { docs: { canvas: { withToolbar: false } } }, +}; + +export const WithToolbar: Story = { + parameters: { docs: { canvas: { withToolbar: true } } }, +}; +export const ThirdStory: Story = {};