-
-
Notifications
You must be signed in to change notification settings - Fork 9.1k
/
data.ts
119 lines (100 loc) · 3.42 KB
/
data.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
import type { Story, StoriesHash } from '@storybook/api';
import { Item } from './types';
export const DEFAULT_REF_ID = 'storybook_internal';
export const collapseAllStories = (stories: StoriesHash) => {
// keep track of component IDs that have been rewritten to the ID of their first leaf child
const componentIdToLeafId: Record<string, string> = {};
// 1) remove all leaves
const leavesRemoved = Object.values(stories).filter(
(item) => !(item.isLeaf && stories[item.parent].isComponent)
);
// 2) make all components leaves and rewrite their ID's to the first leaf child
const componentsFlattened = leavesRemoved.map((item) => {
const { id, isComponent, children, ...rest } = item;
// this is a folder, so just leave it alone
if (!isComponent) {
return item;
}
const nonLeafChildren: string[] = [];
const leafChildren: string[] = [];
children.forEach((child) =>
(stories[child].isLeaf ? leafChildren : nonLeafChildren).push(child)
);
if (leafChildren.length === 0) {
return item; // pass through, we'll handle you later
}
const leafId = leafChildren[0];
const component = {
args: {},
...rest,
id: leafId,
kind: (stories[leafId] as Story).kind,
isRoot: false,
isLeaf: true,
isComponent: true,
children: [] as string[],
};
componentIdToLeafId[id] = leafId;
// this is a component, so it should not have any non-leaf children
if (nonLeafChildren.length !== 0) {
throw new Error(
`Unexpected '${item.id}': ${JSON.stringify({ isComponent, nonLeafChildren })}`
);
}
return component;
});
// 3) rewrite all the children as needed
const childrenRewritten = componentsFlattened.map((item) => {
if (item.isLeaf) {
return item;
}
const { children, ...rest } = item;
const rewritten = children.map((child) => componentIdToLeafId[child] || child);
return { children: rewritten, ...rest };
});
const result = {} as StoriesHash;
childrenRewritten.forEach((item) => {
result[item.id] = item as Item;
});
return result;
};
export const collapseDocsOnlyStories = (storiesHash: StoriesHash) => {
// keep track of component IDs that have been rewritten to the ID of their first leaf child
const componentIdToLeafId: Record<string, string> = {};
const docsOnlyStoriesRemoved = Object.values(storiesHash).filter((item) => {
if (item.isLeaf && item.parameters && item.parameters.docsOnly) {
componentIdToLeafId[item.parent] = item.id;
return false; // filter it out
}
return true;
});
const docsOnlyComponentsCollapsed = docsOnlyStoriesRemoved.map((item) => {
// collapse docs-only components
const { isComponent, children, id } = item;
if (isComponent && children.length === 1) {
const leafId = componentIdToLeafId[id];
if (leafId) {
const collapsed = {
args: {},
...item,
id: leafId,
isLeaf: true,
children: [] as string[],
};
return collapsed;
}
}
// update groups
if (children) {
const rewritten = children.map((child) => componentIdToLeafId[child] || child);
return { ...item, children: rewritten };
}
// pass through stories unmodified
return item;
});
const result = {} as StoriesHash;
docsOnlyComponentsCollapsed.forEach((item) => {
result[item.id] = item as Item;
});
return result;
};