How to use sortableStories method in storybook-root

Best JavaScript code snippet using storybook-root

StoryIndexGenerator.ts

Source: StoryIndexGenerator.ts Github

copy

Full Screen

1import path from 'path';2import fs from 'fs-extra';3import glob from 'globby';4import slash from 'slash';5import type { Path, StoryIndex, V2CompatIndexEntry, StoryId } from '@storybook/​store';6import { autoTitleFromSpecifier, sortStoriesV7 } from '@storybook/​store';7import type { NormalizedStoriesSpecifier } from '@storybook/​core-common';8import { normalizeStoryPath } from '@storybook/​core-common';9import { logger } from '@storybook/​node-logger';10import { readCsfOrMdx, getStorySortParameter } from '@storybook/​csf-tools';11import type { ComponentTitle } from '@storybook/​csf';12type SpecifierStoriesCache = Record<Path, StoryIndex['stories'] | false>;13export class StoryIndexGenerator {14 /​/​ An internal cache mapping specifiers to a set of path=><set of stories>15 /​/​ Later, we'll combine each of these subsets together to form the full index16 private storyIndexEntries: Map<NormalizedStoriesSpecifier, SpecifierStoriesCache>;17 /​/​ Cache the last value of `getStoryIndex`. We invalidate (by unsetting) when:18 /​/​ - any file changes, including deletions19 /​/​ - the preview changes [not yet implemented]20 private lastIndex?: StoryIndex;21 constructor(22 public readonly specifiers: NormalizedStoriesSpecifier[],23 public readonly options: {24 workingDir: Path;25 configDir: Path;26 storiesV2Compatibility: boolean;27 storyStoreV7: boolean;28 }29 ) {30 this.storyIndexEntries = new Map();31 }32 async initialize() {33 /​/​ Find all matching paths for each specifier34 await Promise.all(35 this.specifiers.map(async (specifier) => {36 const pathToSubIndex = {} as SpecifierStoriesCache;37 const fullGlob = slash(38 path.join(this.options.workingDir, specifier.directory, specifier.files)39 );40 const files = await glob(fullGlob);41 files.sort().forEach((absolutePath: Path) => {42 const ext = path.extname(absolutePath);43 const relativePath = path.relative(this.options.workingDir, absolutePath);44 if (!['.js', '.jsx', '.ts', '.tsx', '.mdx'].includes(ext)) {45 logger.info(`Skipping ${ext} file ${relativePath}`);46 return;47 }48 pathToSubIndex[absolutePath] = false;49 });50 this.storyIndexEntries.set(specifier, pathToSubIndex);51 })52 );53 /​/​ Extract stories for each file54 await this.ensureExtracted();55 }56 async ensureExtracted(): Promise<StoryIndex['stories'][]> {57 return (58 await Promise.all(59 this.specifiers.map(async (specifier) => {60 const entry = this.storyIndexEntries.get(specifier);61 return Promise.all(62 Object.keys(entry).map(63 async (absolutePath) =>64 entry[absolutePath] || this.extractStories(specifier, absolutePath)65 )66 );67 })68 )69 ).flat();70 }71 async extractStories(specifier: NormalizedStoriesSpecifier, absolutePath: Path) {72 const relativePath = path.relative(this.options.workingDir, absolutePath);73 const fileStories = {} as StoryIndex['stories'];74 const entry = this.storyIndexEntries.get(specifier);75 try {76 const importPath = slash(normalizeStoryPath(relativePath));77 const defaultTitle = autoTitleFromSpecifier(importPath, specifier);78 const csf = (await readCsfOrMdx(absolutePath, { defaultTitle })).parse();79 csf.stories.forEach(({ id, name }) => {80 fileStories[id] = {81 id,82 title: csf.meta.title,83 name,84 importPath,85 };86 });87 } catch (err) {88 if (err.name === 'NoMetaError') {89 logger.info(`💡 Skipping ${relativePath}: ${err}`);90 } else {91 logger.warn(`🚨 Extraction error on ${relativePath}: ${err}`);92 throw err;93 }94 }95 entry[absolutePath] = fileStories;96 return fileStories;97 }98 async sortStories(storiesList: StoryIndex['stories'][]) {99 const stories: StoryIndex['stories'] = {};100 storiesList.forEach((subStories) => {101 Object.assign(stories, subStories);102 });103 const sortableStories = Object.values(stories);104 /​/​ Skip sorting if we're in v6 mode because we don't have105 /​/​ all the info we need here106 if (this.options.storyStoreV7) {107 const storySortParameter = await this.getStorySortParameter();108 const fileNameOrder = this.storyFileNames();109 sortStoriesV7(sortableStories, storySortParameter, fileNameOrder);110 }111 return sortableStories.reduce((acc, item) => {112 acc[item.id] = item;113 return acc;114 }, {} as StoryIndex['stories']);115 }116 async getIndex() {117 if (this.lastIndex) return this.lastIndex;118 /​/​ Extract any entries that are currently missing119 /​/​ Pull out each file's stories into a list of stories, to be composed and sorted120 const storiesList = await this.ensureExtracted();121 const sorted = await this.sortStories(storiesList);122 let compat = sorted;123 if (this.options.storiesV2Compatibility) {124 const titleToStoryCount = Object.values(sorted).reduce((acc, story) => {125 acc[story.title] = (acc[story.title] || 0) + 1;126 return acc;127 }, {} as Record<ComponentTitle, number>);128 compat = Object.entries(sorted).reduce((acc, entry) => {129 const [id, story] = entry;130 acc[id] = {131 ...story,132 id,133 kind: story.title,134 story: story.name,135 parameters: {136 __id: story.id,137 docsOnly: titleToStoryCount[story.title] === 1 && story.name === 'Page',138 fileName: story.importPath,139 },140 };141 return acc;142 }, {} as Record<StoryId, V2CompatIndexEntry>);143 }144 this.lastIndex = {145 v: 3,146 stories: compat,147 };148 return this.lastIndex;149 }150 invalidate(specifier: NormalizedStoriesSpecifier, importPath: Path, removed: boolean) {151 const absolutePath = slash(path.resolve(this.options.workingDir, importPath));152 const pathToEntries = this.storyIndexEntries.get(specifier);153 if (removed) {154 delete pathToEntries[absolutePath];155 } else {156 pathToEntries[absolutePath] = false;157 }158 this.lastIndex = null;159 }160 async getStorySortParameter() {161 const previewFile = ['js', 'jsx', 'ts', 'tsx']162 .map((ext) => path.join(this.options.configDir, `preview.${ext}`))163 .find((fname) => fs.existsSync(fname));164 let storySortParameter;165 if (previewFile) {166 const previewCode = (await fs.readFile(previewFile, 'utf-8')).toString();167 storySortParameter = await getStorySortParameter(previewCode);168 }169 return storySortParameter;170 }171 /​/​ Get the story file names in "imported order"172 storyFileNames() {173 return Array.from(this.storyIndexEntries.values()).flatMap((r) => Object.keys(r));174 }...

Full Screen

Full Screen

Using AI Code Generation

copy

Full Screen

1import { storiesOf } from '@storybook/​react';2import { withInfo } from '@storybook/​addon-info';3import { withKnobs, text, boolean } from '@storybook/​addon-knobs';4import { action } from '@storybook/​addon-actions';5import { sortableStories } from 'storybook-root';6const stories = storiesOf('Component', module);7sortableStories(stories);8stories.add('Story 1', withInfo()(() => (9)));10stories.add('Story 2', withInfo()(() => (11)));12stories.add('Story 3', withInfo()(() => (13)));14stories.add('Story 4', withInfo()(() => (15)));16stories.add('Story 5', withInfo()(() => (17)));18stories.add('Story 6', withInfo()(() => (19)));20stories.add('Story 7', withInfo()(() => (21)));22stories.add('Story 8', withInfo()(() => (23)));24stories.add('Story 9', withInfo()(() => (25)));26stories.add('Story 10', withInfo()(() => (27)));28stories.add('Story 11', withInfo()(() => (29)));30stories.add('Story 12', withInfo()(() => (31)));32stories.add('Story 13', withInfo()(() => (33)));34stories.add('Story 14', withInfo()(() => (35)));36stories.add('Story 15', withInfo()(() => (37)));38stories.add('Story 16', withInfo()(() => (39)));40stories.add('Story 17', withInfo()(() => (41)));42stories.add('Story 18', withInfo()(() => (

Full Screen

Using AI Code Generation

copy

Full Screen

1import { sortableStories } from 'storybook-root';2import { storiesOf } from '@storybook/​react';3import { withKnobs } from '@storybook/​addon-knobs';4import { withInfo } from '@storybook/​addon-info';5import { withReadme } from 'storybook-readme';6const stories = sortableStories(storiesOf('MyComponent', module));7 .addDecorator(withKnobs)8 .addDecorator(withInfo)9 .addDecorator(withReadme)10 .add('Story 1', () => <MyComponent /​>)11 .add('Story 2', () => <MyComponent /​>)12 .add('Story 3', () => <MyComponent /​>);13import { isSorted } from 'storybook-root';14export function sortableStories(stories) {15 if (isSorted(stories)) {16 return stories;17 }18 return stories.sort((a, b) => a[0].localeCompare(b[0]));19}20export function isSorted(stories) {21 const keys = Object.keys(stories);22 for (let i = 0; i < keys.length - 1; i += 1) {23 if (keys[i] > keys[i + 1]) {24 return false;25 }26 }27 return true;28}

Full Screen

Using AI Code Generation

copy

Full Screen

1import { sortableStories } from './​storybook-root';2import { storiesOf } from './​storybook-root';3import { setAddon } from './​storybook-root';4import { addDecorator } from './​storybook-root';5import { addParameters } from './​storybook-root';6import { configure } from './​storybook-root';7import { getStorybook } from './​storybook-root';8import { raw } from './​storybook-root';9import { forceReRender } from './​storybook-root';10import { setAddon } from './​storybook-root';11import { addDecorator } from './​storybook-root';12import { addParameters } from './​storybook-root';13import { configure } from './​storybook-root';14import { getStorybook } from './​storybook-root';15import { raw } from './​storybook-root';16import { forceReRender } from './​storybook-root';17import { setAddon } from './​storybook-root';18import { addDecorator } from './​storybook-root';19import { addParameters } from './​storybook-root';20import { configure } from './​storybook-root';21import { getStorybook } from './​storybook-root';22import { raw } from './​storybook-root';23import { forceReRender } from './​storybook-root';

Full Screen

Using AI Code Generation

copy

Full Screen

1import { sortableStories } from "storybook-root";2export default sortableStories;3import { storiesOf } from "@storybook/​react";4export const sortableStories = storiesOf("Sortable", module);5import { sortableStories } from "storybook-root";6import Sortable from "./​Sortable";7sortableStories.add("Sortable", () => <Sortable /​>);8import { sortableStories } from "storybook-root";9import Sortable from "./​Sortable";10sortableStories.add("Sortable", () => <Sortable /​>, { name: "Sortable" });11import { sortableStories } from "storybook-root";12import Sortable from "./​Sortable";13sortableStories.add("Sortable", () => <Sortable /​>, { name: "Sortable" });14import { sortableStories } from "storybook-root";15import Sortable from "./​Sortable";16sortableStories.add("Sortable", () => <Sortable /​>, { name: "Sortable" });17import { sortableStories } from "storybook-root";18import Sortable from "./​Sortable";19sortableStories.add("Sortable", () => <Sortable /​>, { name: "Sortable" });20import { sortableStories } from "storybook-root";21import Sortable from "./​Sortable";22sortableStories.add("Sortable", () => <Sortable /​>, { name: "Sortable" });23import { sortableStories } from "storybook-root";24import Sortable from "./​Sortable";25sortableStories.add("Sortable", () => <Sortable /​>, { name: "Sortable" });26import { sortableStories } from "storybook-root";27import Sortable from "./​Sortable";28sortableStories.add("Sortable", () => <Sortable /​>, { name: "Sortable" });29import { sortableStories } from "storybook-root";30import Sortable from "./​Sortable";31sortableStories.add("Sortable", () => <Sortable /​>, { name: "Sortable" });32import { sortableStories

Full Screen

Using AI Code Generation

copy

Full Screen

1import {sortableStories} from 'storybook-root';2export function sortableStories(stories) {3 return stories.sort((a, b) => {4 if (a[1].name < b[1].name) {5 return -1;6 }7 if (a[1].name > b[1].name) {8 return 1;9 }10 return 0;11 });12}13const {sortableStories} = require('./​storybook-root');14module.exports = {15 stories: sortableStories(require.context('../​src', true, /​\.story\.js$/​)),16};

Full Screen

Using AI Code Generation

copy

Full Screen

1import { sortableStories } from 'storybook-root';2const stories = sortableStories(require.context('../​src', true, /​\.stories\.js$/​), 'stories');3stories.forEach(story => {4 story();5});6import { configure } from '@storybook/​react';7import { setOptions } from '@storybook/​addon-options';8import { setDefaults } from 'storybook-root';9setOptions({10});11setDefaults({12});13configure(() => require('../​test'), module);

Full Screen

Using AI Code Generation

copy

Full Screen

1import { sortableStories } from 'storybook-root';2export default {3};4export const NoOrder = () => sortableStories('NoOrder');5export const InOrder = () => sortableStories('InOrder');6export const OutOfOrder = () => sortableStories('OutOfOrder');7export const WithNumbers = () => sortableStories('WithNumbers');8export const WithNumbersAndText = () => sortableStories('WithNumbersAndText');9export const WithNumbersAndTextAndSpecialCharacters = () =>10 sortableStories('WithNumbersAndTextAndSpecialCharacters');11export const WithNumbersAndTextAndSpecialCharactersAndSpaces = () =>12 sortableStories('WithNumbersAndTextAndSpecialCharactersAndSpaces');13export const WithNumbersAndTextAndSpecialCharactersAndSpacesAndUnderscores = () =>14 sortableStories(15 );16export const WithNumbersAndTextAndSpecialCharactersAndSpacesAndUnderscoresAndDashes = () =>17 sortableStories(18 );19export const WithNumbersAndTextAndSpecialCharactersAndSpacesAndUnderscoresAndDashesAndParentheses = () =>20 sortableStories(21 );22export const WithNumbersAndTextAndSpecialCharactersAndSpacesAndUnderscoresAndDashesAndParenthesesAndBrackets = () =>23 sortableStories(24 );25export const WithNumbersAndTextAndSpecialCharactersAndSpacesAndUnderscoresAndDashesAndParenthesesAndBracketsAndBraces = () =>26 sortableStories(27 );28export const WithNumbersAndTextAndSpecialCharactersAndSpacesAndUnderscoresAndDashesAndParenthesesAndBracketsAndBracesAndSlashes = () =>29 sortableStories(30 );

Full Screen

Using AI Code Generation

copy

Full Screen

1import {sortableStories} from 'storybook-root';2import * as stories from 'storybook-root';3import * as stories from 'storybook-root';4import {sortableStories} from 'storybook-root';5import * as stories from 'storybook-root';6import * as stories from 'storybook-root';7import {sortableStories} from 'storybook-root';8import * as stories from 'storybook-root';9import * as stories from 'storybook-root';10import {sortableStories} from 'storybook-root';11import * as stories from 'storybook-root';12import * as stories from 'storybook-root';

Full Screen

Blogs

Check out the latest blogs from LambdaTest on this topic:

Oct’22 Updates: New Analytics And App Automation Dashboard, Test On Google Pixel 7 Series, And More

Hey everyone! We hope you had a great Hacktober. At LambdaTest, we thrive to bring you the best with each update. Our engineering and tech teams work at lightning speed to deliver you a seamless testing experience.

Now Log Bugs Using LambdaTest and DevRev

In today’s world, an organization’s most valuable resource is its customers. However, acquiring new customers in an increasingly competitive marketplace can be challenging while maintaining a strong bond with existing clients. Implementing a customer relationship management (CRM) system will allow your organization to keep track of important customer information. This will enable you to market your services and products to these customers better.

How To Run Cypress Tests In Azure DevOps Pipeline

When software developers took years to create and introduce new products to the market is long gone. Users (or consumers) today are more eager to use their favorite applications with the latest bells and whistles. However, users today don’t have the patience to work around bugs, errors, and design flaws. People have less self-control, and if your product or application doesn’t make life easier for users, they’ll leave for a better solution.

How to Position Your Team for Success in Estimation

Estimates are critical if you want to be successful with projects. If you begin with a bad estimating approach, the project will almost certainly fail. To produce a much more promising estimate, direct each estimation-process issue toward a repeatable standard process. A smart approach reduces the degree of uncertainty. When dealing with presales phases, having the most precise estimation findings can assist you to deal with the project plan. This also helps the process to function more successfully, especially when faced with tight schedules and the danger of deviation.

How To Write End-To-End Tests Using Cypress App Actions

When I started writing tests with Cypress, I was always going to use the user interface to interact and change the application’s state when running tests.

Automation Testing Tutorials

Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.

LambdaTest Learning Hubs:

YouTube

You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.

Run storybook-root automation tests on LambdaTest cloud grid

Perform automation testing on 3000+ real desktop and mobile devices online.

Try LambdaTest Now !!

Get 100 minutes of automation test minutes FREE!!

Next-Gen App & Browser Testing Cloud

Was this article helpful?

Helpful

NotHelpful