@prismai/prism-ladle
Version:
Enhanced component development environment based on Ladle, with multi-project support
129 lines (119 loc) • 3.6 kB
text/typescript
import queryString from "query-string";
import type { StoryTree, StoryOrder } from "../../shared/types";
export const storyDelimiter = "-";
export const storyEncodeDelimiter = "$";
export const getQueryStory = (locationSearch: string, defaultStory: string) =>
(queryString.parse(locationSearch).story as string) || defaultStory;
export const isQueryStorySet = (locationSearch: string) =>
!!queryString.parse(locationSearch).story;
export const capitalize = (s: string) => {
if (typeof s !== "string") return "";
return s.charAt(0).toUpperCase() + s.slice(1);
};
export const storyIdToTitle = (s: string) => {
if (!s) return "";
return s
.split(`${storyDelimiter}${storyDelimiter}`)
.reverse()
.map((level) => capitalize(level.replace(/-/g, " ")))
.join(" - ");
};
export const getStoryTree = (
stories: string[],
selectedStory: string,
allExpanded?: boolean,
) => {
const tree: StoryTree = [];
const addIntoTree = (
_tree: StoryTree,
parts: string[],
selectedParts: string[],
id: string,
) => {
const first = parts.shift();
let isExpanded = allExpanded ? true : false;
let passSelectedParts: string[] = [];
if (selectedParts[0] === first) {
passSelectedParts = [...selectedParts.slice(1)];
isExpanded = true;
}
const itemIndex = _tree.findIndex((item) => item.subId === first);
if (!first) return;
if (itemIndex === -1) {
_tree.push({
id: `${id}${first}`,
subId: first,
name: capitalize(first.replace(/-/g, " ")),
isLinkable: parts.length === 0,
isExpanded,
isFocused: false,
children: [],
});
}
addIntoTree(
_tree[itemIndex > -1 ? itemIndex : _tree.length - 1].children,
parts,
passSelectedParts,
`${id}${first}--`,
);
};
const selectedStoryPath = selectedStory
? selectedStory.split(`${storyDelimiter}${storyDelimiter}`)
: [];
stories.forEach((story) => {
const storyPath = story.split(`${storyDelimiter}${storyDelimiter}`);
addIntoTree(tree, storyPath, selectedStoryPath, "");
});
return tree;
};
// alphabetically sort stories but prefering "folders" over leaf nodes
const storySort = (a: string, b: string) => {
const aParts = a.split("--");
const bParts = b.split("--");
const len = Math.min(aParts.length, bParts.length);
for (let i = 0; i < len; i++) {
if (aParts[i] !== bParts[i]) {
if (!aParts[i + 1] && bParts[i + 1]) {
return 1;
}
if (aParts[i + 1] && !bParts[i + 1]) {
return -1;
}
if ([aParts[i], bParts[i]].sort()[0] === aParts[i]) {
return -1;
} else {
return 1;
}
}
}
return 0;
};
export const sortStories = (stories: string[], storyOrder: StoryOrder) => {
const initialSort = stories.sort(storySort);
let configSort = [...initialSort];
if (Array.isArray(storyOrder)) {
configSort = storyOrder;
} else {
configSort = storyOrder(initialSort);
}
const finalSort = new Set<string>();
configSort.forEach((storyOrig) => {
const story = storyOrig.toLowerCase();
if (story.includes("*")) {
const prefix = story.split("*")[0];
initialSort.forEach((s) => {
if (s.startsWith(prefix)) {
finalSort.add(s);
}
});
} else {
if (!initialSort.includes(story)) {
throw new Error(
`Story "${storyOrig}" does not exist in your storybook. Please check your storyOrder config.`,
);
}
finalSort.add(story);
}
});
return [...finalSort];
};