Closed joeruello closed 7 years ago
Currently, we've no plan to implement that. That's because it makes navigation harder. You can namespace story kinds with dot like "ui.core", "ui.app". Then you can filter them as you need.
If there are a lot of stories, you can start a few storybook instances. You can do that by having two storybook config directories. But, anyway that's an extreme case.
I'm willing to concede this point, and thought I'd just make a different config and run it on a different port and whatnot...
But I think it'd be much better to allow storybook to take multiple config files... and then toggle between named config files, perhaps reloading...
As for UI to switch configs, it would only appear if your config file "loaded" other config files, and it could be sidebar items at the top or bottom of the sidebar nav.
Anyway - I think for larger apps, if you can't (or don't) split out configs, it's kinda crazy.
Adding additional configs seems to be overly complex. What about a toggle for classic/hierarchy view? I'm happy spike out an implementation over the next few days.
This would be a very valuable feature to me as well, but for organization of component types within a single app rather than for multiple apps.
I would be more than happy to provide any help in shaping an implementation that could work for both use cases if this is able to move forward.
@travi One of our another idea is to provide a drop down menu just below the filter box to select the category.
A category is assigned in the config.js and different set of files. So, we can have a another layer of grouping.
I think that type of solution would be enough to satisfy my needs at this point. In addition, I think the namespacing convention mentioned above could still be a reasonable way to assign the category that could be interpreted into the choices in the drop down. Such a solution would enable linking across categories to still remain simple as well.
The way that we're getting around this in the app I'm building (hundreds of components, organized inside loose "pillar" areas) is with a script that dynamically writes out the stories for the area we're currently working on.
find.file(
/\.story\.js/,
path.resolve(__dirname, '../src/app/components', targetComponentPath),
function(files) {
var requires = files.map(function(file) {
return "require('" + path.relative(__dirname, file) + "');";
});
fs.writeFileSync(path.resolve(__dirname, '../.storybook/stories.js'), requires.join("\n"));
}
);
This means that Storybook doesn't even have to build the other components. I would love some level of support for this as a built-in option.
any updates on this one?
+1
I'm argee thats a very useful feature!
+1
+1
+1
+1
+1
+1
Hey @arunoda, has there been any progress on the categories implementation front?
If not, does anyone else have an example app that toggles between two storybook configs?
+1 I absolutely need one additional level of nesting :/
+1
+1
+1
+1
+1
+1
well looks like while your app grows, the components list grows too, and you need some more nesting. 1 more level would already cover much cases
+1
Hey, Guys!
Despite the fact that such a feature isn't planned in the near future this doesn't mean that we can't get such behavior via Storybook Addons API
Here is a such addon:
Any feedback will be very appreciated! :)
@UsulPro Nice!
@UsulPro Storybook Chapters is a brilliant solution. Thanks!
@UsulPro seems to be excactly what I was looking for, thanks!
Hi all! Not trying to compete with @UsulPro (who did an awesome job with storybook-chapters
), but I came up with a small, slightly different solution that allows you to toggle between different groupings of stories with a button in the preview
window. This is useful for us in particular because we want to be able to switch easily between a sort of related components view
a la the bootstrap documentation and a detailed components view
a la what storybook is well-suited for and we have a ton of components to show off. I'd consider this a lightweight version of setting up multiple storybook instances:
If it's useful to you, you can check it out here - https://github.com/majapw/storybook-addon-toggle
I built on @UsulPro's awesome storybook-chapters
to make a storybook loader that will mirror your component file hierarchy as Storybook chapters: storybook-filepath-chapters
With this, I can put my stories in a _stories
file or folder right inline with my components. The loader finds all the story files and maps them into a corresponding navigational structure.
Thanks for the warm feedback, guys!
Really cool to see @hadfieldn's storybook-filepath-chapters
! 👍
I like storybook-addon-toggle
as an example, that it is desirable to have a possibility to build a hierarchy not only in depth but also in the top. Actually, technically it's possible, but I think it's hard to choose the best way (staying within addons API). Perhaps this can be done using decorators (like @majapw) or via addon panels.
I don't plan to add a hierarchy over stories yet, but storybook-chapters
addon now has an API, are able to simplify the construction of such a hierarchy:
enable
/disable
to show/hide your stories
-
With enable/disable feature you can build custom navigation with your preferred logic.
We will be implementing a hierarchy browser, but would love concepts how the community thinks it should be done:
UX wise, I like this idea: http://multi-level-push-menu.make.rs/demo/basichtml/basichtml.html
Configuration I don't know yet.. We could use file exploration and mirror the filesystem, or we could do something like this: https://github.com/sm-react/storybook-chapters/issues/1#issue-215446017
@ndelangen have you given thought to (at least optionally?) allowing the navigation to be defined outside the stories? It seems to me that there might be value in treating how the story looks (the preview area / iframe) and how you want to organize the browsing (the manager) as separate concerns.
@jackmccloy I'm interested, can you tell me more about what you mean?
i've mentioned in a different issue, but my target with categories would be to align mostly with atomic design. pattern lab is the official style guide approach for atomic design, but adding categories to storybook would fill the last remaining gap.
i already arrange my components in top level folders for those categories, so being able to load components into categories based on top level folders would be a great thing the shoot for too.
@travi Can you give me a print of your folder layout?
I'm definitely interested at improving storybook for this exact purpose, But I'm interested what would be technically required to read this categorisation from your folder structure.
its essentially
project root
|
+--
| +-- atoms
| | +-- foo
| | +-- index.js // the component
| | +-- stories.js
...
| +-- molecules
| | +-- bar
| | +-- index.js
| | +-- stories.js
...
| +-- organisms
| | +-- baz
| | +-- index.js
| | +-- stories.js
does that help? i have multiple components under each top level folder, sometimes further grouped by another folder level. happy to provide more detail if it would be helpful
ok, so what we could do is set a flag in config.js
. something like autoDiscoverStories
or so. Which would mean you do not have to import stories manually, and the filesystem folders would be used as categories.
@ndelangen I guess what I'm thinking is this: right now, our conversation is around "how do we make the navigation better", but it assumes that there will be a single navigation that everyone will use. I feel that it might be worth talking about ways to make the navigation extensible, in a similar way to how addons extend the functionality of the stories themselves.
One possibility: Currently, each story is added in two steps - a first step where a category is assigned, and a second step where a title is assigned, i.e.
storiesOf('storyCategory', module).add('storyTitle', () => <Component />)
You can chain adding multiple stories to the same category, but the structure limits flexibility to an extent - all stories must have a category and a title, and categories are a "higher level" than titles.
But if stories could be defined in a slightly different way, i.e.
const storyData = {
category: "category",
title: "storyTitle",
}
stories.add(() => <Component />, storyData)
we could experiment with different navigation options more easily.
The default navigation could stay as it is. It's a sane default, and probably works well enough for most of us. storyData
could even be optional - stories without a category could appear at the top level, and stories without a title could default to the displayName
of the component.
But the community could experiment with different ways of organizing their stories by (a) adding additional metadata fields to stroyData
and/or (b) changing the way the navigation panel renders based on the metadata fields.
Some ideas:
// add an additional level to the hierarchy called subCategory
const stroyData = {
category: "Buttons",
subCategory: "Blue",
title: "BlueButton",
}
stories.add(() => <BlueButton />, storyData)
// add tags to a story that you could then filter by
const stroyData = {
category: "Buttons",
tags: ["button", "homepage"],
title: "HomepageButton",
}
stories.add(() => <HomepageButton />, storyData)
// have a story to appear in multiple categories
const stroyData = {
categories: ["Buttons", "Homepage Elements"],
title: "HomepageButton",
}
stories.add(() => <HomepageButton />, storyData)
Nice! that's quite out of the box, and indeed extensible. I'm going to think about this for a bit. 🤔
Awesome. Let me know what you decide on - I'll pitch in where I can regardless of what direction you choose to go - big fan of the project
@jackmccloy's proposal is great, thanks for the cool idea!
However, it seems to discourage one strong use-case for Storybooks which is thinking about UI as a series of "visual test cases" and easily defining UI states as individual stories using an add()
call per state.
Registering the story metadata in the add()
call feels like it's adding the category at the wrong level. I'd like to see the same proposal, but using the storiesOf()
function:
storiesOf({
title: Component,
category: "My Category"
}, module)
.add("when empty", () => <List items=[] />)
.add("with items", () => <List items=["one", "two", "three"] />)
.add("etc.", () => <List items={etc} />);
I like the idea of just being able to take the title from the Component.displayName
and all the other ideas about sub-categories or adding a component to multiple categories, I'd just like to preserve the simplicity of adding states.
one thing to keep in mind, regardless of where the category is defined, is that another file should be able to add to the category. if a category could only be defined from a single file, i think it would be very limiting
I agree @travi — that's why the category just being a string (which I imagine would map to some dictionary key) is appealing.
I am imagining that I might define my categories in one place to prevent typos like so:
// categories.js
export const Layouts = "Layouts";
export const Components = "Components";
export const Styles = "Styles";
// DashboardLayout.story.js
import { Layouts } from "../categories";
import DashboardLayout from "./DashboardLayout";
storiesOf({
title: DashboardLayout,
category: Layouts
}, module)
.add("default", () => <DashboardLayout />);
but that would be an implementation detail left up to my app.
@theinterned @jackmccloy I like your suggestions.
I'm thinking how you might use your suggestions in a hierarchy of arbitrary depth. Perhaps instead of category
/subCategory
it could be path
with an array of path components. (I know you weren't necessarily intending specifics there, just riffing on your ideas.)
I also like the idea of a configuration option to use the filesystem to create the nav hierarchy. With this option enabled, the path
argument would be optional.
This is more of a stretch goal, but it might be good for each page of stories in the hierarchy to be loaded as a separate chunk, to keep the storybook lightweight as it gets larger. It would also be cool to allow the storybook loader to run with a specific filesystem folder as a root context, so that it could build a storybook with only the stories defined in that folder rather than all the stories in the entire project.
What do you people think about defining / registering categories up front in your config?
// config.js
import { configure, addCategory } from '@kadira/storybook';
function init() {
require('../src/stories');
addCategory({
id: 'atom',
name: 'Atoms',
index: 0
});
addCategory({
id: 'molecule',
name: 'Molecules',
index: 1
})
}
configure(init, module);
// component.story.js
import Component from "./Component";
storiesOf({
title: Component,
category: 'atom'
}, module)
.add("default", () => <DashboardLayout />);
We may as well support an array: category: ['atom', 'deprecated']
, why not?
This would help making sure categories are placed in the right order, which in atomic design, is important.
Retrieving categories from config would be nice, magic string are bad 👎
that makes sense to me.
also, +1 for pulling the category for the story from what was defined in the config rather than hoping to match strings
Would be nice to be able to have "Substories" or a Hierarchy of stories. My case involves various mini "apps" being contained in the same repo. A simple solution would be an option to display stores named like
ui.core.foo
andui.core.bar
like:With support for expanding and collapsing nodes.