function sortEachDepth(orderPerDepth) {
  return (/** @type {Array.<?>} */ a, /** @type {Array.<?>} */ b) => {
    // If the two stories have the same story kind, then use the default
    // ordering, which is the order they are defined in the story file.
    if (a[1].kind === b[1].kind) {
      return 0;
    }
    const storyKindA = a[1].kind.split('/');
    const storyKindB = b[1].kind.split('/');
    let depth = 0;
    let nameA;
    let nameB;
    let indexA;
    let indexB;
    /** @type {Array.<?>} */
    let ordering = orderPerDepth[0] || [];
    if (ordering.indexOf('...') !== -1 && ordering.indexOf('...abc') !== -1) {
      throw new Error(
        `Found ${ordering.join(',')} You need to use either "..." or "...abc" for each level.`,
      );
    }
    // eslint-disable-next-line no-constant-condition
    while (true) {
      nameA = storyKindA[depth] ? storyKindA[depth] : '';
      nameB = storyKindB[depth] ? storyKindB[depth] : '';

      if (nameA === nameB) {
        // We'll need to look at the next part of the name.
        depth += 1;
        ordering = orderPerDepth[depth] || [];
        if (ordering.indexOf('...') !== -1 && ordering.indexOf('...abc') !== -1) {
          throw new Error('You need to use either "..." or "...abc" for each level.');
        }
        // eslint-disable-next-line no-continue
        continue;
      } else {
        // Look for the names in the given `ordering` array.
        indexA = ordering.indexOf(nameA);
        indexB = ordering.indexOf(nameB);

        // If at least one of the names is found, sort by the `ordering` array.
        if (indexA !== -1 || indexB !== -1) {
          // If one of the names is not found in `ordering`, list it at the place of '...' or last.
          let insertPosition = ordering.length;
          if (ordering.indexOf('...') !== -1) {
            insertPosition = ordering.indexOf('...');
          }
          if (ordering.indexOf('...abc') !== -1) {
            insertPosition = ordering.indexOf('...abc');
          }

          if (indexA === -1) {
            indexA = insertPosition;
          }
          if (indexB === -1) {
            indexB = insertPosition;
          }
          return indexA - indexB;
        }
      }
      if (ordering.indexOf('...abc') !== -1) {
        return nameA.localeCompare(nameB);
      }
      // Otherwise, use source code order.
      return 0;
    }
  };
}
Sorts each depth level according to the provided array order.

@example
addParameters({
  options: {
    showRoots: true,
    storySort: sortEachDepth([
      ['Intro', 'Forms', 'Buttons', '...'] // 1. level - ordered like this rest default order
      ['Intro', '...', 'System'], // 2. level - Intro first, System last in between default order
      ['Overview', '...'] // 3. level - Intro first rest default order
    ]),
});

@param {Array.<[]>} orderPerDepth array of arrays giving the order of each level