Skip to content

Commit

Permalink
Merge pull request #17421 from storybookjs/15534-fix-auto-title-dupli…
Browse files Browse the repository at this point in the history
…cates

CSF3: Fix auto-title redundant filename
  • Loading branch information
shilman committed Feb 4, 2022
2 parents 758e4ba + 39b3e6e commit d1cee82
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 6 deletions.
19 changes: 19 additions & 0 deletions MIGRATION.md
@@ -1,5 +1,7 @@
<h1>Migration</h1>

- [From version 6.4.x to 6.5.0](#from-version-64x-to-650)
- [CSF3 auto-title redundant filename](#csf3-auto-title-redundant-filename)
- [From version 6.3.x to 6.4.0](#from-version-63x-to-640)
- [Automigrate](#automigrate)
- [CRA5 upgrade](#cra5-upgrade)
Expand Down Expand Up @@ -188,6 +190,23 @@
- [Packages renaming](#packages-renaming)
- [Deprecated embedded addons](#deprecated-embedded-addons)

## From version 6.4.x to 6.5.0

### CSF3 auto-title redundant filename

SB 6.4 introduced experimental "auto-title", in which a story's location in the sidebar (aka `title`) can be automatically inferred from its location on disk. For example, the file `atoms/Button.stories.js` might result in the title `Atoms/Button`.

The heuristic failed in the common scenario in which each component gets its own directory, e.g. `atoms/Button/Button.stories.js`, which would result in the redundant title `Atoms/Button/Button`. Alternatively, `atoms/Button/index.stories.js` would result in `Atoms/Button/Index`.

To address this problem, 6.5 introduces a new heuristic to removes the filename if it matches the directory name (case insensitive) or `index`. So `atoms/Button/Button.stories.js` and `atoms/Button/index.stories.js` would both result in the title `Atoms/Button`.

Since CSF3 is experimental, we are introducing this technically breaking change in a minor release. If you desire the old structure, you can manually specify the title in file. For example:

```js
// atoms/Button/Button.stories.js
export default { title: 'Atoms/Button/Button' };
```

## From version 6.3.x to 6.4.0

### Automigrate
Expand Down
18 changes: 18 additions & 0 deletions lib/store/src/autoTitle.test.ts
Expand Up @@ -40,6 +40,24 @@ describe('autoTitle', () => {
).toMatchInlineSnapshot(`Atoms/To/File`);
});

it('match with trailing duplicate', () => {
expect(
auto(
'./path/to/button/button.stories.js',
normalizeStoriesEntry({ directory: './path' }, options)
)
).toMatchInlineSnapshot(`To/Button`);
});

it('match with trailing index', () => {
expect(
auto(
'./path/to/button/index.stories.js',
normalizeStoriesEntry({ directory: './path' }, options)
)
).toMatchInlineSnapshot(`To/Button`);
});

it('match with hyphen path', () => {
expect(
auto(
Expand Down
23 changes: 17 additions & 6 deletions lib/store/src/autoTitle.ts
Expand Up @@ -10,8 +10,8 @@ interface NormalizedStoriesSpecifier {
importPathMatcher: RegExp;
}

const stripExtension = (titleWithExtension: string) => {
let parts = titleWithExtension.split('/');
const stripExtension = (path: string[]) => {
let parts = [...path];
const last = parts[parts.length - 1];
const dotIndex = last.indexOf('.');
const stripped = dotIndex > 0 ? last.substr(0, dotIndex) : last;
Expand All @@ -20,11 +20,19 @@ const stripExtension = (titleWithExtension: string) => {
if (first === '') {
parts = rest;
}
return parts.join('/');
return parts;
};

const startCaseTitle = (title: string) => {
return title.split('/').map(startCase).join('/');
// deal with files like "atoms/button/{button,index}.stories.js"
const removeRedundantFilename = (paths: string[]) => {
let prevVal: string;
return paths.filter((val, index) => {
if (index === paths.length - 1 && (val === prevVal || val === 'Index')) {
return false;
}
prevVal = val;
return true;
});
};

/**
Expand All @@ -48,7 +56,10 @@ export const autoTitleFromSpecifier = (fileName: string, entry: NormalizedStorie
if (importPathMatcher.exec(normalizedFileName)) {
const suffix = normalizedFileName.replace(directory, '');
const titleAndSuffix = slash(pathJoin([titlePrefix, suffix]));
return startCaseTitle(stripExtension(titleAndSuffix));
let path = titleAndSuffix.split('/');
path = stripExtension(path).map(startCase);
path = removeRedundantFilename(path);
return path.join('/');
}
return undefined;
};
Expand Down

0 comments on commit d1cee82

Please sign in to comment.