Last active
July 31, 2019 15:30
-
-
Save mpalpha/a39a8b5ec7cb9ec32c5f8952e761d843 to your computer and use it in GitHub Desktop.
sort stories by external array for storybook's "storySort" option
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* "addParameters" in config.js | |
* | |
* addParameters({ | |
* options: { | |
* storySort: sortByArray, | |
* } | |
* }); | |
*/ | |
/* Set your desired menu array order. */ | |
const menuOrder = ['core', 'components']; | |
/* Set your menu sort key. (ex: 'id' or 'kind') */ | |
const menuSortKey = ['kind']; | |
/* Cache a custom collator beforehand for speed. */ | |
const col = new Intl.Collator(undefined, { | |
numeric: true | |
}); | |
/* Generate a custom sort method for given starting `order`. After the given | |
* order, it will ignore casing and place non alphanumeric characters last. | |
* | |
* Sorts in descending order by specified key value with external partial | |
* array matches first. | |
* | |
* Alternatively you may ommit the sort array. | |
* sort descending by key if no array is passed. | |
*/ | |
const sortByArray = (one, two) => { | |
const regAlphaNum = RegExp(/[^A-Za-z0-9]/), | |
oneKey = one[1][menuSortKey].toLowerCase(), | |
twoKey = two[1][menuSortKey].toLowerCase(); | |
// if no sort key exists keep position | |
if (!oneKey && !twoKey) { | |
return 0; | |
} | |
// if first sortkey exists shift up | |
if (!oneKey) { | |
return 1; | |
} | |
// if second sortkey exists shift down | |
if (!twoKey) { | |
return -1; | |
} | |
// get order index for one | |
// whole match | |
// const oneIndex = order.findIndex( | |
// str => oneKey.toLowerCase() == str.toLowerCase() | |
// ); | |
// partial match | |
const oneIndex = menuOrder.findIndex(str => | |
oneKey.toLowerCase().includes(str.toLowerCase()) | |
); | |
// get order index for two | |
// whole match | |
// const twoIndex = order.findIndex( | |
// str => twoKey.toLowerCase() == str.toLowerCase() | |
// ); | |
// partial match | |
const twoIndex = menuOrder.findIndex(str => | |
twoKey.toLowerCase().includes(str.toLowerCase()) | |
); | |
// if one and two found in sort array apply default cached sort, | |
// else sort by one or two if found, | |
// else apply the same sort to non alphanumeric, | |
// else apply default cached sort if needed. | |
return ~oneIndex && ~twoIndex | |
? col.compare(oneIndex, twoIndex) | |
: ~oneIndex | |
? -1 | |
: ~twoIndex || regAlphaNum.test(oneKey) | |
? 1 | |
: regAlphaNum.test(twoKey) || col.compare(oneKey, twoKey); | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment