storybookjs / storybook

Storybook is the industry standard workshop for building, documenting, and testing UI components in isolation
https://storybook.js.org
MIT License
83.93k stars 9.21k forks source link

CSF3 auto generate title exclude file path as the hierarchy? #18545

Open shanpig opened 2 years ago

shanpig commented 2 years ago

Is your feature request related to a problem? Please describe Recent features of the Auto generate title is fabulous, and is a huge relieve to a codebase that maintains hundred of stories. Due to our file structure, however, the story structure that storybook currently generates is a little bit too complicated.

Say our codebase looks like below:

At first thought I set my storybook configuration as:

module.exports = {
stories: [
    {
      directory: '../components',
      titlePrefix: 'components',
      files: '**/*.stories.*',
    },
    {
      directory: '../pages',
      titlePrefix: 'pages',
      files: '**/*.stories.*',
    },
  ],
}

Ths problem now is that storybook actually parses every file hierarchy to the storybook.

but what we think is more easy to read and search is like the structure below:

- Components
  - ComponentA
- Pages
  - ComponentB
  - ComponentC
  - ComponentD

If the title could be generated through a customizable function, or can be only generated by <titlePrefix> + <filename>, I think it would be really helpful. Thanks!

Describe the solution you'd like What would you like to see added to Storybook to solve problem? A means to generate story hierarchy without explicitly listing full file paths Describe alternatives you've considered Any alternative solutions or features you've considered.

Are you able to assist to bring the feature to reality? no | yes, I can...

Additional context Add any other context or screenshots about the feature request here.

Hideman85 commented 2 years ago

I would love to be able to remove also some folder from the hierarchy. My problem is pretty similar, I have a monorepo and so the following:

- packages
  - module-a
    - src
      - components
        - Button
  - module-b
    - src
      - components
        - Something

I would love to regex replace the path to remove src or even components from the name.

ConcernedHobbit commented 12 months ago

We have the same use-case as the comment above, is this doable easily with a custom parser of some sort or does this require contributing?

shilman commented 11 months ago

We generally don't allow configuration via functions because it makes the configurations unwieldy to serialize/persist or programmatically update in codemods.

We could an option to the stories specifier. It's not elegant, but it's simple:

    {
      directory: '../pages',
      files: '**/*.stories.*',
      titlePrefix: 'pages',
      titleStripPath: true,
    },

@storybookjs/core WDYT?

nfarina commented 11 months ago

We have the same monorepo src problem as @Hideman85 - if titleStripPath fixes that then I'm all for it!

Here's our current workaround, that I would love to delete:

// Get all directory names in ../packages.
const filename = fileURLToPath(import.meta.url);
const packagesDir = path.join(filename, "..", "..", "packages");
const packageNames = fs
  .readdirSync(packagesDir)
  .filter((name) => !name.startsWith("."))
  // We need to filter these out or else Storybook will print a bunch of
  // warnings on startup.
  .filter((name) => directoryHasStories(path.join(packagesDir, name, "src")));

export default {
  // We'd prefer to just say:
  //
  //   stories: ["../packages/*/src/**/*.stories.@(ts|tsx)"],
  //
  // But then, Storybook's auto-titles would put "src/" in the title, which
  // we don't want. So we have to do this instead:
  stories: packageNames.map((name) => ({
    directory: `../packages/${name}/src`,
    files: "**/*.stories.tsx",
    titlePrefix: `${name}/`,
  })),
  //
  // (Further config omitted)
  //
} satisfies StorybookConfig;

// Do a recursive search through the given directory for any files with
// ".stories" in their name.
function directoryHasStories(directory: string): boolean {
  const files = fs.readdirSync(directory);

  for (const file of files) {
    const filePath = path.join(directory, file);

    if (file.endsWith(".stories.tsx")) {
      return true;
    } else if (fs.statSync(filePath).isDirectory()) {
      if (directoryHasStories(filePath)) {
        return true;
      }
    }
  }

  return false;
}
yannbf commented 11 months ago

We generally don't allow configuration via functions because it makes the configurations unwieldy to serialize/persist or programmatically update in codemods.

We could an option to the stories specifier. It's not elegant, but it's simple:

    {
      directory: '../pages',
      files: '**/*.stories.*',
      titlePrefix: 'pages',
      titleStripPath: true,
    },

@storybookjs/core WDYT?

That sounds like a solution, maybe we can define a depth level instead, or provide a recipe like mentioned above, or just suggest users to manually override the title in situations like these.

Overall we need to be aware that autotitle is needed for different things, including the test-runner, which would need to support whatever is decided as well