@stories-js/core
Version:
Stories web components to build stories
164 lines • 6.1 kB
JavaScript
/*!
* (C) StoriesJS https://storiesjs.org - GPL-2.0 License
*/
var __rest = (this && this.__rest) || function (s, e) {
var t = {};
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
t[p] = s[p];
if (s != null && typeof Object.getOwnPropertySymbols === "function")
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
t[p[i]] = s[p[i]];
}
return t;
};
/* eslint-disable @typescript-eslint/no-explicit-any */
import { parseKind, sanitize, storyNameFromExport, toId } from "@componentdriven/csf";
import deepmerge from 'deepmerge';
import { state } from '../store';
/**
* Convert [modules](StoryModules) into [stories](StoryComponents)
* @param modules StoryModules
* @returns StoryComponents
*/
export function modulesToStories(modules) {
const result = {};
modules.forEach(mInst => {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const { default: meta = {}, "__esModule": esModule = undefined } = mInst, stories = __rest(mInst, ["default", "__esModule"]);
if (stories) {
const title = meta.title || '';
Object.keys(stories).forEach(key => {
try {
const story = stories[key];
const { storyId, storyName, storyKind } = prepareStoryProperties(key, story.storyName, title);
const storyComponent = createStoryComponent(storyId, storyName, storyKind, story, meta);
result[storyId] = storyComponent;
// eslint-disable-next-line no-empty
}
catch (e) { }
});
}
});
return result;
}
/**
* Convert input parameters to properties of story
* @param storyKey Named export
* @param name StoryName
* @param title Title from Meta
* @returns Object with following props:
* {
* moduleId: string,
* storyId: string,
* storyExportName: string,
* storyName: string,
* storyKind: {root: string | null, groups: string[]
* }
*/
export function prepareStoryProperties(storyKey, name, title) {
const kind = title || name || storyKey;
const storyKind = parseKind(kind, { rootSeparator: '/', groupSeparator: '/' });
const countedKind = [storyKind.root, ...storyKind.groups].filter(value => !!value).join('-');
const moduleId = sanitize(countedKind);
const storyExportName = storyNameFromExport(storyKey);
const storyName = name || storyExportName;
const storyId = toId(moduleId, storyName);
return { moduleId, storyId, storyExportName, storyName, storyKind };
}
/**
* Create instance of [StoryComponent](StoryComponent)
* @param storyId Story ID
* @param storyName Story name
* @param storyKind Story kind
* @param story The story itself
* @param meta The Meta
* @returns The StoryComponent
*/
export function createStoryComponent(storyId, storyName, storyKind, story, meta) {
return {
storyId,
kinds: storyKind.groups,
storyName,
storyFn: story,
component: meta.component,
subcomponents: meta.subcomponents,
// Merging arrays of decorators from meta and story by concatenating them.
decorators: deepmerge(meta.decorators || [], story.decorators || []),
// Merge args from two objects story and meta deeply, returning a new merged object with the elements from both story and meta.
// If an element at the same key is present for both story and meta, the value from story will appear in the result.
// Merging creates a new object, so that neither story or meta is modified.
args: deepmerge(meta.args || {}, story.args || {}),
argTypes: deepmerge(meta.argTypes || {}, story.argTypes || {}),
// Merge parameters from two objects story and meta deeply, returning a new merged object with the elements from both story and meta.
// If an element at the same key is present for both story and meta, the value from story will appear in the result.
// Merging creates a new object, so that neither story or meta is modified.
parameters: deepmerge(meta.parameters || {}, story.parameters || {}),
};
}
/**
* Found the storyId from the URL's hash as defined in the following format:
* #path=storiId
*
* @returns The storyId or undefined
*/
// export function getStoryIdFromURL(): string | undefined {
// const hash = window.location.hash;
// const match = /#.*path=(?<path>[^&]+)/.exec(hash || "");
// return match?.groups?.path;
// }
/**
* Set story Id on URL's hash as following:
* #path=storiId
*
* @param storyId The storyId
*/
// export function setStoryIdInURL(storyId: string | undefined): void {
// window.location.hash = `#path=${storyId ? storyId : ''}`;
// }
export const storiesAPI = {
setStories(modules) {
state.stories = modulesToStories(modules);
},
getStoryIdFromURL() {
var _a;
const hash = window.location.hash;
const match = /#.*path=(?<path>[^&]+)/.exec(hash || "");
return (_a = match === null || match === void 0 ? void 0 : match.groups) === null || _a === void 0 ? void 0 : _a.path;
},
setStoryIdInURL(storyId) {
window.location.hash = `#path=${storyId ? storyId : ''}`;
},
selectFirstStory() {
const keys = Object.keys(state.stories);
const storyId = keys.length ? keys[0] : undefined;
storiesAPI.setStoryIdInURL(storyId);
},
selectStory(storyId) {
if (storyId && state.stories[storyId]) {
storiesAPI.setStoryIdInURL(storyId);
}
else {
storiesAPI.selectFirstStory();
}
},
updateStoryArgs(story, context, newArgs) {
story.args = context.args = newArgs;
},
resetStoryArgs(story, context, argNames) {
if (argNames && argNames.length) {
argNames.forEach(argName => {
story.args[argName] = context.initialArgs[argName];
});
}
else {
story.args = Object.assign({}, context.initialArgs);
}
},
updateStory(story, update) {
story.args = Object.assign({}, update.args);
story.argTypes = Object.assign({}, update.argTypes);
story.parameters = Object.assign({}, update.parameters);
}
};
//# sourceMappingURL=stories.js.map