diff --git a/MIGRATION.md b/MIGRATION.md index 15246311a535..52cb910ef596 100644 --- a/MIGRATION.md +++ b/MIGRATION.md @@ -1,5 +1,7 @@

Migration

+- [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) @@ -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 diff --git a/lib/store/src/autoTitle.test.ts b/lib/store/src/autoTitle.test.ts index 7122e6151009..ced6ade6a679 100644 --- a/lib/store/src/autoTitle.test.ts +++ b/lib/store/src/autoTitle.test.ts @@ -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( diff --git a/lib/store/src/autoTitle.ts b/lib/store/src/autoTitle.ts index a46ba2aeed57..629617faa6bb 100644 --- a/lib/store/src/autoTitle.ts +++ b/lib/store/src/autoTitle.ts @@ -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; @@ -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; + }); }; /** @@ -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; };