mirror of
https://github.com/storybookjs/storybook.git
synced 2025-04-05 16:11:33 +08:00
74 lines
2.4 KiB
TypeScript
74 lines
2.4 KiB
TypeScript
import startCase from 'lodash/startCase';
|
|
import slash from 'slash';
|
|
|
|
// FIXME: types duplicated type from `core-common', to be
|
|
// removed when we remove v6 back-compat.
|
|
interface NormalizedStoriesSpecifier {
|
|
titlePrefix?: string;
|
|
directory: string;
|
|
files?: string;
|
|
importPathMatcher: RegExp;
|
|
}
|
|
|
|
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;
|
|
parts[parts.length - 1] = stripped;
|
|
const [first, ...rest] = parts;
|
|
if (first === '') {
|
|
parts = rest;
|
|
}
|
|
return parts;
|
|
};
|
|
|
|
// 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;
|
|
});
|
|
};
|
|
|
|
/**
|
|
* Combines path parts together, without duplicating separators (slashes). Used instead of `path.join`
|
|
* because this code runs in the browser.
|
|
*
|
|
* @param paths array of paths to join together.
|
|
* @returns joined path string, with single '/' between parts
|
|
*/
|
|
function pathJoin(paths: string[]): string {
|
|
const slashes = new RegExp('/{1,}', 'g');
|
|
return paths.join('/').replace(slashes, '/');
|
|
}
|
|
|
|
export const autoTitleFromSpecifier = (fileName: string, entry: NormalizedStoriesSpecifier) => {
|
|
const { directory, importPathMatcher, titlePrefix = '' } = entry || {};
|
|
// On Windows, backslashes are used in paths, which can cause problems here
|
|
// slash makes sure we always handle paths with unix-style forward slash
|
|
const normalizedFileName = slash(fileName);
|
|
|
|
if (importPathMatcher.exec(normalizedFileName)) {
|
|
const suffix = normalizedFileName.replace(directory, '');
|
|
const titleAndSuffix = slash(pathJoin([titlePrefix, suffix]));
|
|
let path = titleAndSuffix.split('/');
|
|
path = stripExtension(path).map(startCase);
|
|
path = removeRedundantFilename(path);
|
|
return path.join('/');
|
|
}
|
|
return undefined;
|
|
};
|
|
|
|
export const autoTitle = (fileName: string, storiesEntries: NormalizedStoriesSpecifier[]) => {
|
|
for (let i = 0; i < storiesEntries.length; i += 1) {
|
|
const title = autoTitleFromSpecifier(fileName, storiesEntries[i]);
|
|
if (title) return title;
|
|
}
|
|
return undefined;
|
|
};
|