-
SummaryIt used to be like this.
Now only one element is rendered. How to display multiple elements in one Canvas? Additional informationNo response Create a reproductionNo response |
Beta Was this translation helpful? Give feedback.
Replies: 3 comments 6 replies
-
Hi @dmitriybo This isn’t supported anymore. Can you elaborate what’s the necessity for rendering all stories in one canvas? You could just render multiple canvases. Wouldn't this be an alternative? |
Beta Was this translation helpful? Give feedback.
-
8.1 introduces a new Tags feature that provides a viable workaround for this. https://storybook.js.org/docs/writing-stories/tags You can write a story that renders whatever you want, ie. render your button 10 times with different variants in the same story. Then reference that with This isn't exactly what you're asking for, but for anyone out there that want a more flexible canvas that can render more stories/content, please open an RFC that details which problems you want solved and how the existing solutions are inadequate. |
Beta Was this translation helpful? Give feedback.
-
I got a little inspired by this discussion and tried something out. While I couldn't manage to render other existing stories with their args (especially when they have no string template set) in an "allvariants" story in a csf file, without manually writing some tedious stuff, i was able to implement this automated functionality at least for the (auto)Docs-Page via composing all preparedStories as "Story-Blocks" and then "fake" a Canvas-like Block around them to display all the existing Variants in a grid-like preview. A bit like the "Stories"-Block does it for all stories, but without the elements in between. I am posting this here in the case it helps somebody out to implement a customized functionality for themselves in the meantime (ping @dev-nicolaos , @Mauladen). The working draft of a component (in the example, it is used in a custom docs-page autodocs template - usable in non-react frameworks like angular, too. See SB-Documentation): Code: import {
Subheading,
Meta,
DocsContext,
Controls,
Story,
Stories,
Primary,
Source,
} from '@storybook/blocks';
import React, { useContext } from 'react';
import { styled } from '@storybook/theming';
/**
* This container is derived from the `Preview`-Component in storybook/blocks/components (see source code),
* that is responsible for the styling and most of the functionality of the SB Canvas Block we try to copy here.
* But that Preview component is not exported externally,
* so this is a rough draft you can customize to look and behave like the other canvas blocks in your SB.
*/
const CustomPreviewContainer = styled.div({
position: 'relative',
overflow: 'auto',
flexWrap: 'wrap',
margin: '25px 0 40px',
borderRadius: '4px',
background: '#FFFFFF',
boxShadow: '#0000001a 0 1px 3px 0',
border: `1px solid #26557326`,
marginTop: '16px',
});
/**
* Wraps the sum of all variants storys. Responsible to apply some kind of grid to the items.
* Rough draft you can customize to your liking or extend to behave differently for different kind of components ...
*/
const VariantsFlexContainer = styled.div({
padding: '20px',
display: 'flex',
flexWrap: 'wrap',
gap: '20px',
justifyContent: 'space-between',
alignItems: 'flex-start',
});
/**
* Wraps every single story. You could add borders or set different sizes etc ...
*/
const VariantsStoriesWrapper = styled.div({
minWidth: '100px',
});
/**
* A Block that is inspired by the SB Stories Block, instead of mapping Canvas-Blocks it maps Story-Blocks.
* Later we wrap it with the CustomPreviewBlock so that it's styled like the original story or canvas blocks.
* If you wanna implement the toolbar of the original canvas too, maybe take a look at the source code of the canvas block.
*/
const VariantsStories: React.FC<{
stories: any[];
initialPrimaryStoryId: string;
}> = ({ stories, initialPrimaryStoryId }) => {
return (
<>
{stories.map(
(story) =>
story && (
<VariantsStoriesWrapper key={story.id}>
<Story
key={story.id}
of={story.moduleExport}
__forceInitialArgs
__primary={story.id === initialPrimaryStoryId ? false : true}
/>
</VariantsStoriesWrapper>
)
)}
</>
);
};
/**
* Final block that wraps everything and sets a subheading
*/
const CustomVariantsBlock: React.FC<{
stories: any[];
initialPrimaryStoryId: string;
}> = ({ stories, initialPrimaryStoryId }) => (
<>
<Subheading>All Story Variants</Subheading>
<p>All available story variants are shown below.</p>
<CustomPreviewContainer>
<VariantsFlexContainer>
<VariantsStories
stories={stories}
initialPrimaryStoryId={initialPrimaryStoryId}
/>
</VariantsFlexContainer>
</CustomPreviewContainer>
</>
);
export const AutoDocsVariants: React.FC = () => {
const { componentStories, projectAnnotations, getStoryContext } =
useContext(DocsContext);
// Get all csf file stories
let stories = componentStories();
//get the primary, first story of the csf file before filtering and pass it,
//needed to circumvent a weird bug when displaying the same story multiple times on the page
const initialPrimaryStoryId = stories[0].id;
// base filter all csf file stories
const { stories: { filter } = { filter: undefined } } =
projectAnnotations.parameters?.['docs'] || {};
if (filter) {
stories = stories.filter((story) => filter(story, getStoryContext(story)));
}
// Filter to only include stories with 'autodocs' and 'showInVariants' tags
// set tags e.g. `tags: ['autodocs', 'showInVariants']` on the preview, meta or story level, if set in meta, disable at the story or meta level with `'!showInVariants'`,
stories = stories.filter(
(story) =>
story.tags?.includes('autodocs') &&
story.tags?.includes('showInVariants') &&
!story.usesMount
);
return (
<>
<Meta />
{stories.length > 0 && (
<CustomVariantsBlock
stories={stories}
initialPrimaryStoryId={initialPrimaryStoryId}
/>
)}
<Primary />
<Controls />
<Stories includePrimary={false} />
<Source />
</>
);
};
``` |
Beta Was this translation helpful? Give feedback.
8.1 introduces a new Tags feature that provides a viable workaround for this.
https://storybook.js.org/docs/writing-stories/tags
You can write a story that renders whatever you want, ie. render your button 10 times with different variants in the same story. Then reference that with
<Canvas of={ButtonStories.AllButtonVariants} />
. Finally, give the story the tags["!dev", "!test"]
to exclude it from the sidebar and test-runner tests.This isn't exactly what you're asking for, but for anyone out there that want a more flexible canvas that can render more stories/content, please open an RFC that details which problems you want solved and how the existing solutions are inadequate.