Skip to content

Commit

Permalink
Merge pull request #14531 from randak/storysort-wildcard
Browse files Browse the repository at this point in the history
UI: Support `*` wildcard option in storySort order array
  • Loading branch information
shilman authored Apr 10, 2021
2 parents c4942b3 + b8ed01f commit c21a1e2
Show file tree
Hide file tree
Showing 5 changed files with 138 additions and 3 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
```js
// .storybook/preview.js

export const parameters = {
options: {
storySort: {
order: ['Intro', 'Pages', ['Home', 'Login', 'Admin'], 'Components', '*', 'WIP'],
},
},
};
```
14 changes: 14 additions & 0 deletions docs/writing-stories/naming-components-and-hierarchy.md
Original file line number Diff line number Diff line change
Expand Up @@ -129,4 +129,18 @@ Which would result in this story ordering:
7. `Components` and `Components/*` stories
8. All other stories

If you want certain categories to sort to the end of the list, you can insert a `*` into your `order` array to indicate where "all other stories" should go:

<!-- prettier-ignore-start -->

<CodeSnippets
paths={[
'common/storybook-preview-with-ordered-pages-and-wildcard.js.mdx',
]}
/>

<!-- prettier-ignore-end -->

In this example, the `WIP` category would be displayed at the end of the list.

Note that the `order` option is independent of the `method` option; stories are sorted first by the `order` array and then by either the `method: 'alphabetical'` or the default `configure()` import order.
24 changes: 24 additions & 0 deletions lib/client-api/src/storySort.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,10 @@ describe('preview.storySort', () => {
b: ['', { kind: 'b' }],
a_a: ['', { kind: 'a/a' }],
a_b: ['', { kind: 'a/b' }],
a_c: ['', { kind: 'a/c' }],
b_a_a: ['', { kind: 'b/a/a' }],
b_b: ['', { kind: 'b/b' }],
c: ['', { kind: 'c' }],
locale1: ['', { kind: 'Б' }],
locale2: ['', { kind: 'Г' }],
};
Expand Down Expand Up @@ -73,4 +75,26 @@ describe('preview.storySort', () => {
expect(sortFn(fixture.a_a, fixture.a_b)).toBeGreaterThan(0);
expect(sortFn(fixture.a_b, fixture.a_a)).toBeLessThan(0);
});

it('sorts according to the order array with a wildcard', () => {
const sortFn = storySort({ order: ['a', '*', 'b'] });

expect(sortFn(fixture.a, fixture.b)).toBeLessThan(0);
expect(sortFn(fixture.c, fixture.b)).toBeLessThan(0);
expect(sortFn(fixture.b, fixture.c)).toBeGreaterThan(0);
expect(sortFn(fixture.b, fixture.a)).toBeGreaterThan(0);
});

it('sorts according to the nested order array with wildcard', () => {
const sortFn = storySort({ order: ['a', ['a', '*', 'b'], 'c'] });

expect(sortFn(fixture.a, fixture.c)).toBeLessThan(0);
expect(sortFn(fixture.c, fixture.a)).toBeGreaterThan(0);
expect(sortFn(fixture.a_a, fixture.a_b)).toBeLessThan(0);
expect(sortFn(fixture.a_b, fixture.a_a)).toBeGreaterThan(0);
expect(sortFn(fixture.a_a, fixture.a_c)).toBeLessThan(0);
expect(sortFn(fixture.a_c, fixture.a_a)).toBeGreaterThan(0);
expect(sortFn(fixture.a_c, fixture.a_b)).toBeLessThan(0);
expect(sortFn(fixture.a_b, fixture.a_c)).toBeGreaterThan(0);
});
});
16 changes: 13 additions & 3 deletions lib/client-api/src/storySort.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,15 +34,25 @@ export const storySort = (options: StorySortObjectParameter = {}): StorySortComp
// Look for the names in the given `order` array.
let indexA = order.indexOf(nameA);
let indexB = order.indexOf(nameB);
const indexWildcard = order.indexOf('*');

// If at least one of the names is found, sort by the `order` array.
if (indexA !== -1 || indexB !== -1) {
// If one of the names is not found in `order`, list it last.
// If one of the names is not found and there is a wildcard, insert it at the wildcard position.
// Otherwise, list it last.
if (indexA === -1) {
indexA = order.length;
if (indexWildcard !== -1) {
indexA = indexWildcard;
} else {
indexA = order.length;
}
}
if (indexB === -1) {
indexB = order.length;
if (indexWildcard !== -1) {
indexB = indexWildcard;
} else {
indexB = order.length;
}
}

return indexA - indexB;
Expand Down
76 changes: 76 additions & 0 deletions lib/client-api/src/story_store.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1083,6 +1083,42 @@ describe('preview.story_store', () => {
]);
});

it('sorts stories in specified order or alphabetically with wildcards', () => {
const store = new StoryStore({ channel });
store.addGlobalMetadata({
decorators: [],
parameters: {
options: {
storySort: {
method: 'alphabetical',
order: ['b', ['bc', '*', 'bb'], '*', 'c'],
},
},
},
});
addStoryToStore(store, 'a/b', '1', () => 0);
addStoryToStore(store, 'a', '1', () => 0);
addStoryToStore(store, 'c', '1', () => 0);
addStoryToStore(store, 'b/bd', '1', () => 0);
addStoryToStore(store, 'b/bb', '1', () => 0);
addStoryToStore(store, 'b/ba', '1', () => 0);
addStoryToStore(store, 'b/bc', '1', () => 0);
addStoryToStore(store, 'b', '1', () => 0);

const extracted = store.extract();

expect(Object.keys(extracted)).toEqual([
'b--1',
'b-bc--1',
'b-ba--1',
'b-bd--1',
'b-bb--1',
'a--1',
'a-b--1',
'c--1',
]);
});

it('sorts stories in specified order or by configure order', () => {
const store = new StoryStore({ channel });
store.addGlobalMetadata({
Expand Down Expand Up @@ -1119,6 +1155,46 @@ describe('preview.story_store', () => {
]);
});

it('sorts stories in specified order or by configure order with wildcard', () => {
const store = new StoryStore({ channel });
store.addGlobalMetadata({
decorators: [],
parameters: {
options: {
storySort: {
method: 'configure',
order: ['b', '*', 'c'],
},
},
},
});
addStoryToStore(store, 'a/b', '1', () => 0);
addStoryToStore(store, 'a', '1', () => 0);
addStoryToStore(store, 'c', '1', () => 0);
addStoryToStore(store, 'b/bd', '1', () => 0);
addStoryToStore(store, 'b/bb', '1', () => 0);
addStoryToStore(store, 'b/ba', '1', () => 0);
addStoryToStore(store, 'b/bc', '1', () => 0);
addStoryToStore(store, 'b', '1', () => 0);
addStoryToStore(store, 'e', '1', () => 0);
addStoryToStore(store, 'd', '1', () => 0);

const extracted = store.extract();

expect(Object.keys(extracted)).toEqual([
'b--1',
'b-bd--1',
'b-bb--1',
'b-ba--1',
'b-bc--1',
'a--1',
'a-b--1',
'e--1',
'd--1',
'c--1',
]);
});

it('passes kind and global parameters to sort', () => {
const store = new StoryStore({ channel });
const storySort = jest.fn();
Expand Down

0 comments on commit c21a1e2

Please sign in to comment.