diff --git a/code/core/src/csf-tools/ConfigFile.ts b/code/core/src/csf-tools/ConfigFile.ts index e531693e689a..b13e42175a45 100644 --- a/code/core/src/csf-tools/ConfigFile.ts +++ b/code/core/src/csf-tools/ConfigFile.ts @@ -319,7 +319,7 @@ export class ConfigFile { return _getPathProperties(rest, exported); } - getFieldValue(path: string[]) { + getFieldValue(path: string[]): T | undefined { const node = this.getFieldNode(path); if (node) { const { code } = generate(node, {}); diff --git a/code/core/src/types/modules/indexer.ts b/code/core/src/types/modules/indexer.ts index a34a2422766c..ceb3bf915e51 100644 --- a/code/core/src/types/modules/indexer.ts +++ b/code/core/src/types/modules/indexer.ts @@ -3,7 +3,7 @@ import type { StoryId, ComponentTitle, StoryName, Parameters, Tag, Path } from ' type ExportName = string; type MetaId = string; -interface StoriesSpecifier { +export interface StoriesSpecifier { /** * When auto-titling, what to prefix all generated titles with (default: '') */ diff --git a/code/lib/cli/src/generators/configure.test.ts b/code/lib/cli/src/generators/configure.test.ts index cd54a95c34f1..d0e593a3c026 100644 --- a/code/lib/cli/src/generators/configure.test.ts +++ b/code/lib/cli/src/generators/configure.test.ts @@ -29,7 +29,7 @@ describe('configureMain', () => { expect(mainConfigContent).toMatchInlineSnapshot(` "/** @type { import('@storybook/react-vite').StorybookConfig } */ const config = { - stories: ['../stories/**/*.mdx', '../stories/**/*.stories.@(js|jsx|mjs)'], + stories: ['../stories/**/*.mdx', '../stories/**/*.stories.@(js|jsx|mjs|ts|tsx)'], addons: [], framework: { name: '@storybook/react-vite', @@ -95,7 +95,7 @@ describe('configureMain', () => { /** @type { import('@storybook/react-webpack5').StorybookConfig } */ const config = { - stories: ['../stories/**/*.mdx', '../stories/**/*.stories.@(js|jsx|mjs)'], + stories: ['../stories/**/*.mdx', '../stories/**/*.stories.@(js|jsx|mjs|ts|tsx)'], addons: [ path.dirname(require.resolve(path.join('@storybook/addon-links', 'package.json'))), path.dirname(require.resolve(path.join('@storybook/addon-essentials', 'package.json'))), diff --git a/code/lib/cli/src/generators/configure.ts b/code/lib/cli/src/generators/configure.ts index a2c30f5198f5..73c57dfc8fa3 100644 --- a/code/lib/cli/src/generators/configure.ts +++ b/code/lib/cli/src/generators/configure.ts @@ -49,8 +49,6 @@ const sanitizeFramework = (framework: string) => { return matches[0]; }; -const typescriptExtensions = ['ts', 'tsx', 'mts', 'cts']; - export async function configureMain({ addons, extensions = ['js', 'jsx', 'mjs', 'ts', 'tsx'], @@ -59,14 +57,10 @@ export async function configureMain({ prefixes = [], ...custom }: ConfigureMainOptions) { - const isLanguageJavascript = language === SupportedLanguage.JAVASCRIPT; - const filteredExtensions = extensions.filter((extension) => - isLanguageJavascript ? !typescriptExtensions.includes(extension) : true - ); const srcPath = path.resolve(storybookConfigFolder, '../src'); const prefix = (await fse.pathExists(srcPath)) ? '../src' : '../stories'; const config = { - stories: [`${prefix}/**/*.mdx`, `${prefix}/**/*.stories.@(${filteredExtensions.join('|')})`], + stories: [`${prefix}/**/*.mdx`, `${prefix}/**/*.stories.@(${extensions.join('|')})`], addons, ...custom, }; diff --git a/code/lib/cli/src/sandbox-templates.ts b/code/lib/cli/src/sandbox-templates.ts index cf3020564924..9ca026b4c8d0 100644 --- a/code/lib/cli/src/sandbox-templates.ts +++ b/code/lib/cli/src/sandbox-templates.ts @@ -1,4 +1,5 @@ -import type { StorybookConfigRaw } from '@storybook/core/types'; +import type { StoriesEntry, StorybookConfigRaw } from '@storybook/core/types'; +import type { ConfigFile } from '@storybook/core/csf-tools'; export type SkippableTask = | 'smoke-test' @@ -70,7 +71,9 @@ export type Template = { */ modifications?: { skipTemplateStories?: boolean; - mainConfig?: Partial; + mainConfig?: + | Partial + | ((config: ConfigFile) => Partial); testBuild?: boolean; disableDocs?: boolean; extraDependencies?: string[]; @@ -100,6 +103,20 @@ const baseTemplates = { builder: '@storybook/builder-webpack5', }, skipTasks: ['e2e-tests-dev', 'bench'], + modifications: { + mainConfig: (config) => { + const stories = config.getFieldValue>(['stories']); + return { + stories: stories?.map((s) => { + if (typeof s === 'string') { + return s.replace(/\|(tsx?|ts)\b|\b(tsx?|ts)\|/g, ''); + } else { + return s; + } + }), + }; + }, + }, }, 'cra/default-ts': { name: 'Create React App Latest (Webpack | TypeScript)', diff --git a/scripts/tasks/sandbox-parts.ts b/scripts/tasks/sandbox-parts.ts index a5a9214da08b..13e9d5dcbd99 100644 --- a/scripts/tasks/sandbox-parts.ts +++ b/scripts/tasks/sandbox-parts.ts @@ -42,6 +42,7 @@ import { workspacePath } from '../utils/workspace'; import { babelParse } from '../../code/core/src/csf-tools/babelParse'; import { CODE_DIRECTORY, REPROS_DIRECTORY } from '../utils/constants'; import type { TemplateKey } from '../../code/lib/cli/src/sandbox-templates'; +import { isFunction } from 'lodash'; const logger = console; @@ -278,7 +279,9 @@ function addStoriesEntry(mainConfig: ConfigFile, path: string, disableDocs: bool const entry = { directory: slash(join('../template-stories', path)), titlePrefix: slash(path), - files: disableDocs ? '**/*.stories.@(js|jsx|ts|tsx)' : '**/*.@(mdx|stories.@(js|jsx|ts|tsx))', + files: disableDocs + ? '**/*.stories.@(js|jsx|mjs|ts|tsx)' + : '**/*.@(mdx|stories.@(js|jsx|mjs|ts|tsx))', }; mainConfig.setFieldValue(['stories'], [...stories, entry]); @@ -536,7 +539,9 @@ export const extendMain: Task['run'] = async ({ template, sandboxDir, key }, { d addRefs(mainConfig); } - const templateConfig = template.modifications?.mainConfig || {}; + const templateConfig = isFunction(template.modifications?.mainConfig) + ? template.modifications?.mainConfig(mainConfig) + : template.modifications?.mainConfig || {}; const configToAdd = { ...templateConfig, features: {