Skip to content

Instantly share code, notes, and snippets.

@mpalpha
Last active July 31, 2019 15:30
Show Gist options
  • Save mpalpha/a39a8b5ec7cb9ec32c5f8952e761d843 to your computer and use it in GitHub Desktop.
Save mpalpha/a39a8b5ec7cb9ec32c5f8952e761d843 to your computer and use it in GitHub Desktop.
sort stories by external array for storybook's "storySort" option
/*
* "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