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:

Webinar: Move Forward With An Effective Test Automation Strategy [Voices of Community]

The key to successful test automation is to focus on tasks that maximize the return on investment (ROI), ensuring that you are automating the right tests and automating them in the right way. This is where test automation strategies come into play.

Six Agile Team Behaviors to Consider

Are members of agile teams different from members of other teams? Both yes and no. Yes, because some of the behaviors we observe in agile teams are more distinct than in non-agile teams. And no, because we are talking about individuals!

Different Ways To Style CSS Box Shadow Effects

Have you ever visited a website that only has plain text and images? Most probably, no. It’s because such websites do not exist now. But there was a time when websites only had plain text and images with almost no styling. For the longest time, websites did not focus on user experience. For instance, this is how eBay’s homepage looked in 1999.

How To Find Hidden Elements In Selenium WebDriver With Java

Have you ever struggled with handling hidden elements while automating a web or mobile application? I was recently automating an eCommerce application. I struggled with handling hidden elements on the web page.

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