UNPKG

2.71 kBJavaScriptView Raw
1const STORY_KIND_PATH_SEPARATOR = /\s*\/\s*/;
2export const storySort = (options = {}) => (a, b) => {
3 // If the two stories have the same story kind, then use the default
4 // ordering, which is the order they are defined in the story file.
5 // only when includeNames is falsy
6 if (a[1].kind === b[1].kind && !options.includeNames) {
7 return 0;
8 } // Get the StorySortParameter options.
9
10
11 const method = options.method || 'configure';
12 let order = options.order || []; // Examine each part of the story kind in turn.
13
14 const storyKindA = a[1].kind.trim().split(STORY_KIND_PATH_SEPARATOR);
15 const storyKindB = b[1].kind.trim().split(STORY_KIND_PATH_SEPARATOR);
16
17 if (options.includeNames) {
18 storyKindA.push(a[1].name);
19 storyKindB.push(b[1].name);
20 }
21
22 let depth = 0;
23
24 while (storyKindA[depth] || storyKindB[depth]) {
25 // Stories with a shorter depth should go first.
26 if (!storyKindA[depth]) {
27 return -1;
28 }
29
30 if (!storyKindB[depth]) {
31 return 1;
32 } // Compare the next part of the story kind.
33
34
35 const nameA = storyKindA[depth];
36 const nameB = storyKindB[depth];
37
38 if (nameA !== nameB) {
39 // Look for the names in the given `order` array.
40 let indexA = order.indexOf(nameA);
41 let indexB = order.indexOf(nameB);
42 const indexWildcard = order.indexOf('*'); // If at least one of the names is found, sort by the `order` array.
43
44 if (indexA !== -1 || indexB !== -1) {
45 // If one of the names is not found and there is a wildcard, insert it at the wildcard position.
46 // Otherwise, list it last.
47 if (indexA === -1) {
48 if (indexWildcard !== -1) {
49 indexA = indexWildcard;
50 } else {
51 indexA = order.length;
52 }
53 }
54
55 if (indexB === -1) {
56 if (indexWildcard !== -1) {
57 indexB = indexWildcard;
58 } else {
59 indexB = order.length;
60 }
61 }
62
63 return indexA - indexB;
64 } // Use the default configure() order.
65
66
67 if (method === 'configure') {
68 return 0;
69 } // Otherwise, use alphabetical order.
70
71
72 return nameA.localeCompare(nameB, options.locales ? options.locales : undefined, {
73 numeric: true,
74 sensitivity: 'accent'
75 });
76 } // If a nested array is provided for a name, use it for ordering.
77
78
79 const index = order.indexOf(nameA);
80 order = index !== -1 && Array.isArray(order[index + 1]) ? order[index + 1] : []; // We'll need to look at the next part of the name.
81
82 depth += 1;
83 } // Identical story kinds. The shortcut at the start of this function prevents
84 // this from ever being used.
85
86 /* istanbul ignore next */
87
88
89 return 0;
90};
\No newline at end of file