UNPKG

storybook-multilevel-sort

Version:

Applies specific sort order to more than two levels of chapters and stories in a storybook.

1 lines 11.3 kB
{"version":3,"file":"index.cjs","sources":["index.js"],"sourcesContent":["// See https://github.com/storybookjs/storybook/issues/548#issuecomment-1099949201\n\nconst hasKey = Object.hasOwn\n ? (obj, key) => Object.hasOwn(obj, key)\n /* c8 ignore next */\n : (obj, key) => Object.prototype.hasOwnProperty.call(obj, key)\nconst compareAlphabetical = (name1, name2) => name1.localeCompare(name2, { numeric: true })\n\nconst compareStoryPaths = (order, path1, path2, context) => {\n /* c8 ignore next 9 */\n if (path1.length === 0 && path2.length === 0) {\n return 0\n }\n if (path1.length === 0 && path2.length > 0) {\n // Path1 must be an ancestor of path2\n return -1\n }\n if (path1.length > 0 && path2.length === 0) {\n // Path2 must be an ancestor of path1\n /* c8 ignore next 2 */\n return 1\n }\n\n const [path1Head, ...path1Tail] = path1\n const [path2Head, ...path2Tail] = path2\n\n if (!order) {\n // No reference order, so just sort alphabetically\n const result = context.compareNames(path1Head, path2Head, { path1, path2 })\n if (result === 0) {\n return compareStoryPaths(null, path1Tail, path2Tail, context)\n }\n return result\n }\n\n let currentOrder\n const updateOrderAndCompare = (newOrder, path1, path2) => {\n // Propagate the nested wildcard to the following call to compareStoryPaths\n const nestedOrder = order['**']\n if (nestedOrder) context.order = nestedOrder\n currentOrder = newOrder\n // If the same paths are going to be compared, do not use the nested wildcard\n // any more; it'd enter this clause once more and end up with a stack overflow\n if (!currentOrder && context.path1 !== path1 && context.path2 !== path2) {\n currentOrder = context.order\n }\n // Remember the current paths for future calls to compareStoryPaths\n context.path1 = path1\n context.path2 = path2\n return compareStoryPaths(currentOrder, path1, path2, context)\n }\n\n if (path1Head === path2Head) {\n // The two paths share the same head; try either the key for the head, or the\n // wildcard keys, otherwise pass `undefined` to sort without an explicit order\n return updateOrderAndCompare(order[path1Head] || order['*'], path1Tail, path2Tail)\n }\n\n if (hasKey(order, path1Head) && hasKey(order, path2Head)) {\n // If both heads are in the reference order, use the ordering of the keys in the reference order\n const orderKeys = Object.keys(order)\n\n return orderKeys.indexOf(path1Head) < orderKeys.indexOf(path2Head) ? -1 : 1\n }\n if (hasKey(order, path1Head) && !hasKey(order, path2Head)) {\n return -1 // Give preference to path1, since it is included in the reference order\n }\n if (!hasKey(order, path1Head) && hasKey(order, path2Head)) {\n return 1 // Give preference to path2, since it is included in the reference order\n }\n // No explicit order for the path heads was found, try the wildcard key,\n // otherwise pass `undefined` to sort without an explicit order\n return updateOrderAndCompare(order['*'], path1, path2)\n}\n\nconst compareTypes = (type1, type2, { typeOrder = ['docs', 'story'] } = {}) => {\n // No ordedring of types means the same weight for all page typed and using\n // only alphabetical comparison of story names.\n if (!typeOrder.length) return 0\n\n let index1 = typeOrder.indexOf(type1)\n let index2 = typeOrder.indexOf(type2)\n\n // If some of the types does not have an explicitly specified order, try\n // assigning it the order of the wildcard type (`*`).\n if (index1 < 0 || index2 < 0) {\n const wildcardIndex = typeOrder.indexOf('*')\n if (wildcardIndex >= 0) {\n if (index1 < 0) index1 = wildcardIndex\n if (index2 < 0) index2 = wildcardIndex\n }\n }\n\n if (index1 >= 0) {\n // If both types have their indexes in the type-ordering array, apply\n // the usual numeric comparison on the type indexes.\n if (index2 >= 0) {\n /* c8 ignore next */\n return index1 === index2 ? 0 : index1 < index2 ? -1 : 1\n }\n // If just the first type was found, the first story should go to the front.\n return -1\n }\n // If just the second type was found, the second story should go to the front.\n if (index2 >= 0) {\n return 1\n }\n // If no type as found, both stories will start with the same weight\n // in the just following name comparison.\n return 0\n}\n\nexport const compareStories = (storyOrder, story1, story2, { typeOrder, compareNames } = {}) => {\n const { title: title1, name: name1, type: type1 } = story1\n const { title: title2, name: name2, type: type2 } = story2\n\n // If the types are different and are not considered the same in the comparison,\n // they alone are enough to decide the order of the stories and this group\n // stories of the same type together. Only if the two stories are in the same\n // group. Ancestor group names should be still sorted alphabetically.\n if (type1 !== type2 && title1 === title2) {\n const result = compareTypes(type1, type2, { typeOrder })\n if (result) return result\n }\n\n // Extract case-insensitive name paths from story titles. For example:\n // { title: 'Elements/Button', name: 'Documentation' }\n // => [ 'elements', 'button', 'documentation' ]\n // { title: 'Elements/Link', name: 'Active' }\n // => [ 'elements', 'link', 'active' ]\n const story1Path = [...title1.split('/'), name1].map(key => key.toLowerCase())\n const story2Path = [...title2.split('/'), name2].map(key => key.toLowerCase())\n\n if (!compareNames) compareNames = compareAlphabetical\n return compareStoryPaths(storyOrder, story1Path, story2Path, { compareNames })\n}\n\nexport const storySort = (story1, story2) => {\n // A global object with the configuration is set by `configureSort`.\n const params = globalThis['storybook-multilevel-sort:params']\n if (!params) throw new Error('Missing storybook-multilevel-sort:params object. Forgot to call configureSort?')\n\n const { storyOrder, typeOrder, compareNames } = params\n return compareStories(storyOrder, story1, story2, { typeOrder, compareNames })\n}\n\nexport const configureSort = ({ storyOrder, typeOrder, compareNames } = {}) => {\n const params = globalThis['storybook-multilevel-sort:params'] ||\n // biome-ignore lint/suspicious/noAssignInExpressions: this is easier to read\n (globalThis['storybook-multilevel-sort:params'] = {})\n if (storyOrder !== undefined) params.storyOrder = storyOrder\n if (typeOrder !== undefined) params.typeOrder = typeOrder\n if (compareNames !== undefined) params.compareNames = compareNames\n\n globalThis['storybook-multilevel-sort:storySort'] = storySort\n}\n"],"names":[],"mappings":"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"}