From 120702e8fe0b23c11888da2f6de7c34c8d15d72e Mon Sep 17 00:00:00 2001 From: Boris Novikov Date: Thu, 5 Oct 2023 22:31:41 +0200 Subject: [PATCH 01/17] feat: update storybook paths --- packages/project-config/src/paths.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/project-config/src/paths.ts b/packages/project-config/src/paths.ts index 84304e5ee4f4..15716ad71146 100644 --- a/packages/project-config/src/paths.ts +++ b/packages/project-config/src/paths.ts @@ -112,9 +112,9 @@ const PATH_WEB_DIR_ENTRY_SERVER = 'web/src/entry.server' // .jsx,.tsx const PATH_WEB_DIR_ENTRIES = 'web/src/entries' // .js,.ts const PATH_WEB_DIR_CONFIG_POSTCSS = 'web/config/postcss.config.js' -const PATH_WEB_DIR_CONFIG_STORYBOOK_CONFIG = 'web/config/storybook.config.js' -const PATH_WEB_DIR_CONFIG_STORYBOOK_PREVIEW = 'web/config/storybook.preview.js' -const PATH_WEB_DIR_CONFIG_STORYBOOK_MANAGER = 'web/config/storybook.manager.js' +const PATH_WEB_DIR_CONFIG_STORYBOOK_CONFIG = 'web/config/storybook.config' // .js,.ts +const PATH_WEB_DIR_CONFIG_STORYBOOK_PREVIEW = 'web/config/storybook.preview' // .js, .tsx +const PATH_WEB_DIR_CONFIG_STORYBOOK_MANAGER = 'web/config/storybook.manager' // .js, .ts const PATH_WEB_DIR_DIST = 'web/dist' const PATH_WEB_DIR_DIST_SERVER = 'web/dist/server' From 26cb17f91e3505972c14dd9afac46b80dce4be52 Mon Sep 17 00:00:00 2001 From: Boris Novikov Date: Thu, 5 Oct 2023 22:35:26 +0200 Subject: [PATCH 02/17] feat: create storybook tsx templates --- .../templates/storybook.preview.tsx.template | 41 +++++++++++++++++++ .../chakra.storybook.preview.tsx.template | 17 ++++++++ .../mantine.storybook.preview.tsx.template | 15 +++++++ .../templates/storybook.preview.tsx.template | 15 +++++++ 4 files changed, 88 insertions(+) create mode 100644 packages/cli/src/commands/setup/i18n/templates/storybook.preview.tsx.template create mode 100644 packages/cli/src/commands/setup/ui/templates/chakra.storybook.preview.tsx.template create mode 100644 packages/cli/src/commands/setup/ui/templates/mantine.storybook.preview.tsx.template create mode 100644 packages/cli/src/lib/templates/storybook.preview.tsx.template diff --git a/packages/cli/src/commands/setup/i18n/templates/storybook.preview.tsx.template b/packages/cli/src/commands/setup/i18n/templates/storybook.preview.tsx.template new file mode 100644 index 000000000000..41492420346c --- /dev/null +++ b/packages/cli/src/commands/setup/i18n/templates/storybook.preview.tsx.template @@ -0,0 +1,41 @@ +import * as React from 'react' +import { I18nextProvider } from 'react-i18next' +import type { GlobalTypes } from '@storybook/csf' +import type { StoryFn, StoryContext } from '@storybook/react' +import i18n from 'web/src/i18n' + +export const globalTypes: GlobalTypes = { + locale: { + name: 'Locale', + description: 'Internationalization locale', + defaultValue: 'en', + toolbar: { + icon: 'globe', + items: [ + { value: 'en', right: '🇺🇸', title: 'English' }, + { value: 'fr', right: '🇫🇷', title: 'Français' }, + ], + }, + }, +} + +/** + * We're following Storybook's naming convention here. See for example + * https://github.com/storybookjs/addon-kit/blob/main/src/withGlobals.ts + * Unfortunately that will make eslint complain, so we have to disable it when + * using a hook below + */ +const withI18n = (StoryFn: StoryFn, context: StoryContext) => { + // eslint-disable-next-line react-hooks/rules-of-hooks + React.useEffect(() => { + i18n.changeLanguage(context.globals.locale) + }, [context.globals.locale]) + + return ( + + + + ) +} + +export const decorators = [withI18n] diff --git a/packages/cli/src/commands/setup/ui/templates/chakra.storybook.preview.tsx.template b/packages/cli/src/commands/setup/ui/templates/chakra.storybook.preview.tsx.template new file mode 100644 index 000000000000..c27e590222bc --- /dev/null +++ b/packages/cli/src/commands/setup/ui/templates/chakra.storybook.preview.tsx.template @@ -0,0 +1,17 @@ +import * as React from 'react' + +import { ChakraProvider, extendTheme } from '@chakra-ui/react' +import type { StoryFn } from '@storybook/react' +import theme from 'config/chakra.config' + +const extendedTheme = extendTheme(theme) + +const withChakra = (StoryFn: StoryFn) => { + return ( + + + + ) +} + +export const decorators = [withChakra] diff --git a/packages/cli/src/commands/setup/ui/templates/mantine.storybook.preview.tsx.template b/packages/cli/src/commands/setup/ui/templates/mantine.storybook.preview.tsx.template new file mode 100644 index 000000000000..fdfbad6577e8 --- /dev/null +++ b/packages/cli/src/commands/setup/ui/templates/mantine.storybook.preview.tsx.template @@ -0,0 +1,15 @@ +import * as React from 'react' + +import { MantineProvider } from '@mantine/core' +import type { StoryFn } from '@storybook/react' +import theme from 'config/mantine.config' + +const withMantine = (StoryFn: StoryFn) => { + return ( + + + + ) +} + +export const decorators = [withMantine] diff --git a/packages/cli/src/lib/templates/storybook.preview.tsx.template b/packages/cli/src/lib/templates/storybook.preview.tsx.template new file mode 100644 index 000000000000..932cab366cac --- /dev/null +++ b/packages/cli/src/lib/templates/storybook.preview.tsx.template @@ -0,0 +1,15 @@ +import * as React from 'react' + +import type { GlobalTypes } from '@storybook/csf' +import type { StoryFn, StoryContext } from '@storybook/react' + +export const globalTypes: GlobalTypes = {} + +/** + * An example, no-op storybook decorator. Use a function like this to create decorators. +*/ +const _exampleDecorator = (StoryFn: StoryFn, _context: StoryContext) => { + return +} + +export const decorators = [] From 737feba13ef35aa7581c86361adda1d8e8a26f4d Mon Sep 17 00:00:00 2001 From: Boris Novikov Date: Thu, 5 Oct 2023 22:36:02 +0200 Subject: [PATCH 03/17] feat: update storybook template paths --- packages/cli/src/commands/setup/i18n/i18nHandler.js | 2 +- packages/cli/src/commands/setup/ui/libraries/chakra-ui.js | 2 +- packages/cli/src/commands/setup/ui/libraries/mantine.js | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/cli/src/commands/setup/i18n/i18nHandler.js b/packages/cli/src/commands/setup/i18n/i18nHandler.js index 1e07e255ba81..2ce5ea053171 100644 --- a/packages/cli/src/commands/setup/i18n/i18nHandler.js +++ b/packages/cli/src/commands/setup/i18n/i18nHandler.js @@ -171,7 +171,7 @@ export const handler = async ({ force }) => { skip: () => fileIncludes(rwPaths.web.storybookConfig, 'withI18n'), task: async () => extendStorybookConfiguration( - path.join(__dirname, 'templates', 'storybook.preview.js.template') + path.join(__dirname, 'templates', 'storybook.preview.tsx.template') ), }, { diff --git a/packages/cli/src/commands/setup/ui/libraries/chakra-ui.js b/packages/cli/src/commands/setup/ui/libraries/chakra-ui.js index e088883d4177..b34ea1a3fb57 100644 --- a/packages/cli/src/commands/setup/ui/libraries/chakra-ui.js +++ b/packages/cli/src/commands/setup/ui/libraries/chakra-ui.js @@ -108,7 +108,7 @@ export async function handler({ force, install }) { __dirname, '..', 'templates', - 'chakra.storybook.preview.js.template' + 'chakra.storybook.preview.tsx.template' ) ), }, diff --git a/packages/cli/src/commands/setup/ui/libraries/mantine.js b/packages/cli/src/commands/setup/ui/libraries/mantine.js index 8723df80c2c0..50265fdcbea5 100644 --- a/packages/cli/src/commands/setup/ui/libraries/mantine.js +++ b/packages/cli/src/commands/setup/ui/libraries/mantine.js @@ -129,7 +129,7 @@ export async function handler({ force, install, packages }) { __dirname, '..', 'templates', - 'mantine.storybook.preview.js.template' + 'mantine.storybook.preview.tsx.template' ) ), }, From 2fabf184f7310bb46cc39f4d32a3d2411ac5c3cf Mon Sep 17 00:00:00 2001 From: Boris Novikov Date: Thu, 5 Oct 2023 22:59:59 +0200 Subject: [PATCH 04/17] feat: remove storybook js templates --- .../templates/storybook.preview.js.template | 44 ------------------- .../chakra.storybook.preview.js.template | 16 ------- .../mantine.storybook.preview.js.template | 14 ------ .../templates/storybook.preview.js.template | 16 ------- 4 files changed, 90 deletions(-) delete mode 100644 packages/cli/src/commands/setup/i18n/templates/storybook.preview.js.template delete mode 100644 packages/cli/src/commands/setup/ui/templates/chakra.storybook.preview.js.template delete mode 100644 packages/cli/src/commands/setup/ui/templates/mantine.storybook.preview.js.template delete mode 100644 packages/cli/src/lib/templates/storybook.preview.js.template diff --git a/packages/cli/src/commands/setup/i18n/templates/storybook.preview.js.template b/packages/cli/src/commands/setup/i18n/templates/storybook.preview.js.template deleted file mode 100644 index 512bcf7b67b3..000000000000 --- a/packages/cli/src/commands/setup/i18n/templates/storybook.preview.js.template +++ /dev/null @@ -1,44 +0,0 @@ -import * as React from 'react' -import { I18nextProvider } from 'react-i18next' -import i18n from 'web/src/i18n' - -/** @type { import("@storybook/csf").GlobalTypes } */ -export const globalTypes = { - locale: { - name: 'Locale', - description: 'Internationalization locale', - defaultValue: 'en', - toolbar: { - icon: 'globe', - items: [ - { value: 'en', right: '🇺🇸', title: 'English' }, - { value: 'fr', right: '🇫🇷', title: 'Français' }, - ], - }, - }, -} - -/** - * We're following Storybook's naming convention here. See for example - * https://github.com/storybookjs/addon-kit/blob/main/src/withGlobals.ts - * Unfortunately that will make eslint complain, so we have to disable it when - * using a hook below - * - * @param { import("@storybook/addons").StoryFn} StoryFn - * @param { import("@storybook/addons").StoryContext} context - * @returns a story wrapped in an I18nextProvider - */ -const withI18n = (StoryFn, context) => { - // eslint-disable-next-line react-hooks/rules-of-hooks - React.useEffect(() => { - i18n.changeLanguage(context.globals.locale) - }, [context.globals.locale]) - - return ( - - - - ) -} - -export const decorators = [withI18n] diff --git a/packages/cli/src/commands/setup/ui/templates/chakra.storybook.preview.js.template b/packages/cli/src/commands/setup/ui/templates/chakra.storybook.preview.js.template deleted file mode 100644 index b6afe7aa1769..000000000000 --- a/packages/cli/src/commands/setup/ui/templates/chakra.storybook.preview.js.template +++ /dev/null @@ -1,16 +0,0 @@ -import * as React from 'react' - -import { ChakraProvider, extendTheme } from '@chakra-ui/react' -import * as theme from 'config/chakra.config' - -const extendedTheme = extendTheme(theme) - -const withChakra = (StoryFn) => { - return ( - - - - ) -} - -export const decorators = [withChakra] diff --git a/packages/cli/src/commands/setup/ui/templates/mantine.storybook.preview.js.template b/packages/cli/src/commands/setup/ui/templates/mantine.storybook.preview.js.template deleted file mode 100644 index becfab191a9f..000000000000 --- a/packages/cli/src/commands/setup/ui/templates/mantine.storybook.preview.js.template +++ /dev/null @@ -1,14 +0,0 @@ -import * as React from 'react' - -import { MantineProvider } from '@mantine/core' -import * as theme from 'config/mantine.config' - -const withMantine = (StoryFn) => { - return ( - - - - ) -} - -export const decorators = [withMantine] diff --git a/packages/cli/src/lib/templates/storybook.preview.js.template b/packages/cli/src/lib/templates/storybook.preview.js.template deleted file mode 100644 index 8241d88fab17..000000000000 --- a/packages/cli/src/lib/templates/storybook.preview.js.template +++ /dev/null @@ -1,16 +0,0 @@ -import * as React from 'react' - -/** @type { import("@storybook/csf").GlobalTypes } */ -export const globalTypes = {} - -/** - * An example, no-op storybook decorator. Use a function like this to create decorators. - * @param { import("@storybook/addons").StoryFn} StoryFn - * @param { import("@storybook/addons").StoryContext} context - * @returns StoryFn, unmodified. - */ -const _exampleDecorator = (StoryFn, _context) => { - return -} - -export const decorators = [] From a20e396fa1e44ab5b5eb8b8457be829c92ff7480 Mon Sep 17 00:00:00 2001 From: Boris Novikov Date: Tue, 17 Oct 2023 17:39:40 +0200 Subject: [PATCH 05/17] feat: add support for ts/tsx files --- packages/cli/src/lib/merge/index.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/cli/src/lib/merge/index.js b/packages/cli/src/lib/merge/index.js index cee121f97d34..35c97981294d 100644 --- a/packages/cli/src/lib/merge/index.js +++ b/packages/cli/src/lib/merge/index.js @@ -212,7 +212,9 @@ function mergeAST(baseAST, extAST, strategy = {}) { export function merge(base, extension, strategy) { function parseReact(code) { return parse(code, { - presets: ['@babel/preset-react'], + filename: 'merge.tsx', + presets: ['@babel/preset-react', '@babel/preset-typescript'], + plugins: ['@babel/plugin-transform-typescript'], }) } From 3953f322dd3133f5169dfa571f3f0b6a657436e3 Mon Sep 17 00:00:00 2001 From: Boris Novikov Date: Tue, 17 Oct 2023 17:41:33 +0200 Subject: [PATCH 06/17] feat: use tsx storybook template --- packages/cli/src/lib/configureStorybook.js | 40 ++++++++++++++++------ 1 file changed, 30 insertions(+), 10 deletions(-) diff --git a/packages/cli/src/lib/configureStorybook.js b/packages/cli/src/lib/configureStorybook.js index cccb7ba18276..d55d7e5900d8 100644 --- a/packages/cli/src/lib/configureStorybook.js +++ b/packages/cli/src/lib/configureStorybook.js @@ -1,5 +1,4 @@ import path from 'path' -import util from 'util' import fse from 'fs-extra' import prettier from 'prettier' @@ -11,24 +10,45 @@ import { keepBoth, keepBothStatementParents, } from './merge/strategy' +import { isTypeScriptProject } from './project' -import { getPaths } from '.' +import { getPaths, transformTSToJS, writeFile } from '.' +/** + * Extends the Storybook configuration file with the new configuration file + * @param {string} newConfigPath - The path to the new configuration file + */ export default async function extendStorybookConfiguration( newConfigPath = undefined ) { - const sbPreviewConfigPath = getPaths().web.storybookPreviewConfig + const ts = isTypeScriptProject() + const sbPreviewConfigPath = `${getPaths().web.storybookPreviewConfig}.${ + ts ? 'tsx' : 'js' + }` + const read = (path) => fse.readFileSync(path, { encoding: 'utf-8' }) + if (!fse.existsSync(sbPreviewConfigPath)) { - await util.promisify(fse.cp)( - path.join(__dirname, 'templates', 'storybook.preview.js.template'), - sbPreviewConfigPath + // If the Storybook preview config file doesn't exist, create it from the template + const templateContent = read( + path.resolve(__dirname, 'templates', 'storybook.preview.tsx.template') ) + const storybookPreviewContent = ts + ? templateContent + : transformTSToJS(sbPreviewConfigPath, templateContent) + + await writeFile(sbPreviewConfigPath, storybookPreviewContent) } + const storybookPreviewContent = read(sbPreviewConfigPath) + if (newConfigPath) { - const read = (path) => fse.readFileSync(path, { encoding: 'utf-8' }) - const write = (path, data) => fse.writeFileSync(path, data) - const merged = merge(read(sbPreviewConfigPath), read(newConfigPath), { + // If the new config file path is provided, merge it with the Storybook preview config file + const newConfigTemplate = read(newConfigPath) + const newConfigContent = ts + ? newConfigTemplate + : transformTSToJS(newConfigPath, newConfigTemplate) + + const merged = merge(storybookPreviewContent, newConfigContent, { ImportDeclaration: interleave, ArrayExpression: concatUnique, ObjectExpression: concatUnique, @@ -41,6 +61,6 @@ export default async function extendStorybookConfiguration( ...(await prettier.resolveConfig(sbPreviewConfigPath)), }) - write(sbPreviewConfigPath, formatted) + writeFile(sbPreviewConfigPath, formatted, { overwriteExisting: true }) } } From a373973b724e12a829d67fa12f236927c5a93e10 Mon Sep 17 00:00:00 2001 From: Boris Novikov Date: Tue, 17 Oct 2023 17:42:02 +0200 Subject: [PATCH 07/17] feat: read tsx storybook preview config if the project is ts --- packages/testing/config/storybook/main.js | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/packages/testing/config/storybook/main.js b/packages/testing/config/storybook/main.js index 2a098541103b..b24180ce13e3 100644 --- a/packages/testing/config/storybook/main.js +++ b/packages/testing/config/storybook/main.js @@ -13,6 +13,10 @@ const { const redwoodProjectConfig = getConfig() const redwoodProjectPaths = getPaths() +const isTypeScriptProject = + fs.existsSync(path.join(redwoodProjectPaths.web.base, 'tsconfig.json')) || + fs.existsSync(path.join(redwoodProjectPaths.api.base, 'tsconfig.json')) + /** @type { import('@storybook/react-webpack5').StorybookConfig } */ const baseConfig = { framework: { @@ -74,10 +78,12 @@ const baseConfig = { } } - const userPreviewPath = fs.existsSync( - redwoodProjectPaths.web.storybookPreviewConfig - ) - ? redwoodProjectPaths.web.storybookPreviewConfig + const sbPreviewConfigPath = `${getPaths().web.storybookPreviewConfig}.${ + isTypeScriptProject ? 'tsx' : 'js' + }` + + const userPreviewPath = fs.existsSync(sbPreviewConfigPath) + ? sbPreviewConfigPath : './preview.example.js' sbConfig.resolve.alias['~__REDWOOD__USER_STORYBOOK_PREVIEW_CONFIG'] = userPreviewPath From 1e3bf75468bb08dd41f2872cb695d9339b097f33 Mon Sep 17 00:00:00 2001 From: Boris Novikov Date: Thu, 19 Oct 2023 00:35:48 +0200 Subject: [PATCH 08/17] fix: failing tests --- .../src/__tests__/paths.test.ts | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/packages/project-config/src/__tests__/paths.test.ts b/packages/project-config/src/__tests__/paths.test.ts index cad05c0c4780..016f84a33753 100644 --- a/packages/project-config/src/__tests__/paths.test.ts +++ b/packages/project-config/src/__tests__/paths.test.ts @@ -129,19 +129,19 @@ describe('paths', () => { FIXTURE_BASEDIR, 'web', 'config', - 'storybook.config.js' + 'storybook.config' ), storybookPreviewConfig: path.join( FIXTURE_BASEDIR, 'web', 'config', - 'storybook.preview.js' + 'storybook.preview' ), storybookManagerConfig: path.join( FIXTURE_BASEDIR, 'web', 'config', - 'storybook.manager.js' + 'storybook.manager' ), dist: path.join(FIXTURE_BASEDIR, 'web', 'dist'), distEntryServer: path.join( @@ -409,19 +409,19 @@ describe('paths', () => { FIXTURE_BASEDIR, 'web', 'config', - 'storybook.config.js' + 'storybook.config' ), storybookPreviewConfig: path.join( FIXTURE_BASEDIR, 'web', 'config', - 'storybook.preview.js' + 'storybook.preview' ), storybookManagerConfig: path.join( FIXTURE_BASEDIR, 'web', 'config', - 'storybook.manager.js' + 'storybook.manager' ), dist: path.join(FIXTURE_BASEDIR, 'web', 'dist'), distEntryServer: path.join( @@ -735,19 +735,19 @@ describe('paths', () => { FIXTURE_BASEDIR, 'web', 'config', - 'storybook.config.js' + 'storybook.config' ), storybookPreviewConfig: path.join( FIXTURE_BASEDIR, 'web', 'config', - 'storybook.preview.js' + 'storybook.preview' ), storybookManagerConfig: path.join( FIXTURE_BASEDIR, 'web', 'config', - 'storybook.manager.js' + 'storybook.manager' ), entryClient: null, entryServer: null, @@ -1018,19 +1018,19 @@ describe('paths', () => { FIXTURE_BASEDIR, 'web', 'config', - 'storybook.config.js' + 'storybook.config' ), storybookPreviewConfig: path.join( FIXTURE_BASEDIR, 'web', 'config', - 'storybook.preview.js' + 'storybook.preview' ), storybookManagerConfig: path.join( FIXTURE_BASEDIR, 'web', 'config', - 'storybook.manager.js' + 'storybook.manager' ), dist: path.join(FIXTURE_BASEDIR, 'web', 'dist'), distEntryServer: path.join( From 1904f2a4445d56d3ea0a8cb4b0ba0a7c911664bf Mon Sep 17 00:00:00 2001 From: Boris Novikov Date: Thu, 19 Oct 2023 00:45:47 +0200 Subject: [PATCH 09/17] revert: ts support for storybook manager and config files --- .../project-config/src/__tests__/paths.test.ts | 16 ++++++++-------- packages/project-config/src/paths.ts | 5 ++--- 2 files changed, 10 insertions(+), 11 deletions(-) diff --git a/packages/project-config/src/__tests__/paths.test.ts b/packages/project-config/src/__tests__/paths.test.ts index 016f84a33753..0011f4c14dc1 100644 --- a/packages/project-config/src/__tests__/paths.test.ts +++ b/packages/project-config/src/__tests__/paths.test.ts @@ -129,7 +129,7 @@ describe('paths', () => { FIXTURE_BASEDIR, 'web', 'config', - 'storybook.config' + 'storybook.config.js' ), storybookPreviewConfig: path.join( FIXTURE_BASEDIR, @@ -141,7 +141,7 @@ describe('paths', () => { FIXTURE_BASEDIR, 'web', 'config', - 'storybook.manager' + 'storybook.manager.js' ), dist: path.join(FIXTURE_BASEDIR, 'web', 'dist'), distEntryServer: path.join( @@ -409,7 +409,7 @@ describe('paths', () => { FIXTURE_BASEDIR, 'web', 'config', - 'storybook.config' + 'storybook.config.js' ), storybookPreviewConfig: path.join( FIXTURE_BASEDIR, @@ -421,7 +421,7 @@ describe('paths', () => { FIXTURE_BASEDIR, 'web', 'config', - 'storybook.manager' + 'storybook.manager.js' ), dist: path.join(FIXTURE_BASEDIR, 'web', 'dist'), distEntryServer: path.join( @@ -735,7 +735,7 @@ describe('paths', () => { FIXTURE_BASEDIR, 'web', 'config', - 'storybook.config' + 'storybook.config.js' ), storybookPreviewConfig: path.join( FIXTURE_BASEDIR, @@ -747,7 +747,7 @@ describe('paths', () => { FIXTURE_BASEDIR, 'web', 'config', - 'storybook.manager' + 'storybook.manager.js' ), entryClient: null, entryServer: null, @@ -1018,7 +1018,7 @@ describe('paths', () => { FIXTURE_BASEDIR, 'web', 'config', - 'storybook.config' + 'storybook.config.js' ), storybookPreviewConfig: path.join( FIXTURE_BASEDIR, @@ -1030,7 +1030,7 @@ describe('paths', () => { FIXTURE_BASEDIR, 'web', 'config', - 'storybook.manager' + 'storybook.manager.js' ), dist: path.join(FIXTURE_BASEDIR, 'web', 'dist'), distEntryServer: path.join( diff --git a/packages/project-config/src/paths.ts b/packages/project-config/src/paths.ts index 6656104f9bf2..e823292f7f00 100644 --- a/packages/project-config/src/paths.ts +++ b/packages/project-config/src/paths.ts @@ -118,10 +118,9 @@ const PATH_WEB_DIR_ENTRIES = 'web/src/entries' // .js,.ts const PATH_WEB_DIR_GRAPHQL = 'web/src/graphql' // .js,.ts const PATH_WEB_DIR_CONFIG_POSTCSS = 'web/config/postcss.config.js' -const PATH_WEB_DIR_CONFIG_STORYBOOK_CONFIG = 'web/config/storybook.config' // .js,.ts +const PATH_WEB_DIR_CONFIG_STORYBOOK_CONFIG = 'web/config/storybook.config.js' const PATH_WEB_DIR_CONFIG_STORYBOOK_PREVIEW = 'web/config/storybook.preview' // .js, .tsx -const PATH_WEB_DIR_CONFIG_STORYBOOK_MANAGER = 'web/config/storybook.manager' // .js, .ts - +const PATH_WEB_DIR_CONFIG_STORYBOOK_MANAGER = 'web/config/storybook.manager.js' const PATH_WEB_DIR_DIST = 'web/dist' const PATH_WEB_DIR_DIST_SERVER = 'web/dist/server' const PATH_WEB_DIR_DIST_SERVER_ENTRY_SERVER = 'web/dist/server/entry.server.js' From 8a292c06371682e0db815034adda52bd5af4438c Mon Sep 17 00:00:00 2001 From: Boris Novikov Date: Thu, 19 Oct 2023 01:06:18 +0200 Subject: [PATCH 10/17] revert: type annotations for js storybook preview files --- .../setup/i18n/templates/storybook.preview.tsx.template | 3 +++ .../setup/ui/templates/chakra.storybook.preview.tsx.template | 3 +++ .../setup/ui/templates/mantine.storybook.preview.tsx.template | 3 +++ packages/cli/src/lib/templates/storybook.preview.tsx.template | 3 +++ 4 files changed, 12 insertions(+) diff --git a/packages/cli/src/commands/setup/i18n/templates/storybook.preview.tsx.template b/packages/cli/src/commands/setup/i18n/templates/storybook.preview.tsx.template index 41492420346c..a481f82c015a 100644 --- a/packages/cli/src/commands/setup/i18n/templates/storybook.preview.tsx.template +++ b/packages/cli/src/commands/setup/i18n/templates/storybook.preview.tsx.template @@ -4,6 +4,7 @@ import type { GlobalTypes } from '@storybook/csf' import type { StoryFn, StoryContext } from '@storybook/react' import i18n from 'web/src/i18n' +/** @type { import("@storybook/csf").GlobalTypes } */ export const globalTypes: GlobalTypes = { locale: { name: 'Locale', @@ -24,6 +25,8 @@ export const globalTypes: GlobalTypes = { * https://github.com/storybookjs/addon-kit/blob/main/src/withGlobals.ts * Unfortunately that will make eslint complain, so we have to disable it when * using a hook below + * @param { import("@storybook/react").StoryFn} StoryFn + * @param { import("@storybook/react").StoryContext} context */ const withI18n = (StoryFn: StoryFn, context: StoryContext) => { // eslint-disable-next-line react-hooks/rules-of-hooks diff --git a/packages/cli/src/commands/setup/ui/templates/chakra.storybook.preview.tsx.template b/packages/cli/src/commands/setup/ui/templates/chakra.storybook.preview.tsx.template index c27e590222bc..692d6611e1c5 100644 --- a/packages/cli/src/commands/setup/ui/templates/chakra.storybook.preview.tsx.template +++ b/packages/cli/src/commands/setup/ui/templates/chakra.storybook.preview.tsx.template @@ -6,6 +6,9 @@ import theme from 'config/chakra.config' const extendedTheme = extendTheme(theme) +/* + * @param { import("@storybook/react").StoryFn} StoryFn + */ const withChakra = (StoryFn: StoryFn) => { return ( diff --git a/packages/cli/src/commands/setup/ui/templates/mantine.storybook.preview.tsx.template b/packages/cli/src/commands/setup/ui/templates/mantine.storybook.preview.tsx.template index fdfbad6577e8..0fff8fc3dec9 100644 --- a/packages/cli/src/commands/setup/ui/templates/mantine.storybook.preview.tsx.template +++ b/packages/cli/src/commands/setup/ui/templates/mantine.storybook.preview.tsx.template @@ -4,6 +4,9 @@ import { MantineProvider } from '@mantine/core' import type { StoryFn } from '@storybook/react' import theme from 'config/mantine.config' +/* + * @param { import("@storybook/react").StoryFn} StoryFn + */ const withMantine = (StoryFn: StoryFn) => { return ( diff --git a/packages/cli/src/lib/templates/storybook.preview.tsx.template b/packages/cli/src/lib/templates/storybook.preview.tsx.template index 932cab366cac..042497ff6196 100644 --- a/packages/cli/src/lib/templates/storybook.preview.tsx.template +++ b/packages/cli/src/lib/templates/storybook.preview.tsx.template @@ -3,10 +3,13 @@ import * as React from 'react' import type { GlobalTypes } from '@storybook/csf' import type { StoryFn, StoryContext } from '@storybook/react' +/** @type { import("@storybook/csf").GlobalTypes } */ export const globalTypes: GlobalTypes = {} /** * An example, no-op storybook decorator. Use a function like this to create decorators. + * @param { import("@storybook/react").StoryFn} StoryFn + * @param { import("@storybook/react").StoryContext} context */ const _exampleDecorator = (StoryFn: StoryFn, _context: StoryContext) => { return From 40aabfdbd3ec4f271f4994e4962f7e370d204bce Mon Sep 17 00:00:00 2001 From: Boris Novikov Date: Mon, 6 Nov 2023 12:25:24 +0100 Subject: [PATCH 11/17] feat: include 'config' directory in web tsconfig --- .gitignore | 1 + packages/create-redwood-app/templates/ts/web/tsconfig.json | 1 + 2 files changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index 553242a9d907..b7c70b01b192 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ *.icloud +.cosine .idea .DS_Store node_modules diff --git a/packages/create-redwood-app/templates/ts/web/tsconfig.json b/packages/create-redwood-app/templates/ts/web/tsconfig.json index 8b5649abe5a4..5dc323bff5f4 100644 --- a/packages/create-redwood-app/templates/ts/web/tsconfig.json +++ b/packages/create-redwood-app/templates/ts/web/tsconfig.json @@ -31,6 +31,7 @@ }, "include": [ "src", + "config", "../.redwood/types/includes/all-*", "../.redwood/types/includes/web-*", "../types", From a476d18cd33b32e550308718b05437bdf89f44ad Mon Sep 17 00:00:00 2001 From: Boris Novikov Date: Mon, 6 Nov 2023 12:45:18 +0100 Subject: [PATCH 12/17] fix: regenerate fixtures, crwa, fix comment type --- __fixtures__/test-project/package.json | 5 +---- __fixtures__/test-project/web/package.json | 2 +- __fixtures__/test-project/web/tsconfig.json | 1 + .../setup/ui/templates/chakra.storybook.preview.tsx.template | 2 +- .../ui/templates/mantine.storybook.preview.tsx.template | 2 +- packages/create-redwood-app/templates/js/web/jsconfig.json | 1 + 6 files changed, 6 insertions(+), 7 deletions(-) diff --git a/__fixtures__/test-project/package.json b/__fixtures__/test-project/package.json index 34c31882e78d..800f1c3724f5 100644 --- a/__fixtures__/test-project/package.json +++ b/__fixtures__/test-project/package.json @@ -20,8 +20,5 @@ "prisma": { "seed": "yarn rw exec seed" }, - "packageManager": "yarn@3.6.3", - "resolutions": { - "@types/react": "18.2.14" - } + "packageManager": "yarn@3.6.3" } diff --git a/__fixtures__/test-project/web/package.json b/__fixtures__/test-project/web/package.json index 02a6dc8b0fb2..57f543c33bfd 100644 --- a/__fixtures__/test-project/web/package.json +++ b/__fixtures__/test-project/web/package.json @@ -27,6 +27,6 @@ "postcss": "^8.4.31", "postcss-loader": "^7.3.3", "prettier-plugin-tailwindcss": "0.4.1", - "tailwindcss": "^3.3.3" + "tailwindcss": "^3.3.5" } } diff --git a/__fixtures__/test-project/web/tsconfig.json b/__fixtures__/test-project/web/tsconfig.json index 8b5649abe5a4..5dc323bff5f4 100644 --- a/__fixtures__/test-project/web/tsconfig.json +++ b/__fixtures__/test-project/web/tsconfig.json @@ -31,6 +31,7 @@ }, "include": [ "src", + "config", "../.redwood/types/includes/all-*", "../.redwood/types/includes/web-*", "../types", diff --git a/packages/cli/src/commands/setup/ui/templates/chakra.storybook.preview.tsx.template b/packages/cli/src/commands/setup/ui/templates/chakra.storybook.preview.tsx.template index 692d6611e1c5..627ffd2f02fc 100644 --- a/packages/cli/src/commands/setup/ui/templates/chakra.storybook.preview.tsx.template +++ b/packages/cli/src/commands/setup/ui/templates/chakra.storybook.preview.tsx.template @@ -6,7 +6,7 @@ import theme from 'config/chakra.config' const extendedTheme = extendTheme(theme) -/* +/** * @param { import("@storybook/react").StoryFn} StoryFn */ const withChakra = (StoryFn: StoryFn) => { diff --git a/packages/cli/src/commands/setup/ui/templates/mantine.storybook.preview.tsx.template b/packages/cli/src/commands/setup/ui/templates/mantine.storybook.preview.tsx.template index 0fff8fc3dec9..df40e67459bb 100644 --- a/packages/cli/src/commands/setup/ui/templates/mantine.storybook.preview.tsx.template +++ b/packages/cli/src/commands/setup/ui/templates/mantine.storybook.preview.tsx.template @@ -4,7 +4,7 @@ import { MantineProvider } from '@mantine/core' import type { StoryFn } from '@storybook/react' import theme from 'config/mantine.config' -/* +/** * @param { import("@storybook/react").StoryFn} StoryFn */ const withMantine = (StoryFn: StoryFn) => { diff --git a/packages/create-redwood-app/templates/js/web/jsconfig.json b/packages/create-redwood-app/templates/js/web/jsconfig.json index 0ee3041e4b2f..3f5be910a4f3 100644 --- a/packages/create-redwood-app/templates/js/web/jsconfig.json +++ b/packages/create-redwood-app/templates/js/web/jsconfig.json @@ -43,6 +43,7 @@ }, "include": [ "src", + "config", "../.redwood/types/includes/all-*", "../.redwood/types/includes/web-*", "../types", From 2c5e9d0ea5c0e3edf9f70f25aa69636e5d008659 Mon Sep 17 00:00:00 2001 From: Boris Novikov Date: Tue, 7 Nov 2023 13:40:29 +0100 Subject: [PATCH 13/17] fix: add backward compatibility for ts users --- packages/testing/config/storybook/main.js | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/packages/testing/config/storybook/main.js b/packages/testing/config/storybook/main.js index b24180ce13e3..1b4f5b89066b 100644 --- a/packages/testing/config/storybook/main.js +++ b/packages/testing/config/storybook/main.js @@ -13,10 +13,6 @@ const { const redwoodProjectConfig = getConfig() const redwoodProjectPaths = getPaths() -const isTypeScriptProject = - fs.existsSync(path.join(redwoodProjectPaths.web.base, 'tsconfig.json')) || - fs.existsSync(path.join(redwoodProjectPaths.api.base, 'tsconfig.json')) - /** @type { import('@storybook/react-webpack5').StorybookConfig } */ const baseConfig = { framework: { @@ -78,13 +74,17 @@ const baseConfig = { } } - const sbPreviewConfigPath = `${getPaths().web.storybookPreviewConfig}.${ - isTypeScriptProject ? 'tsx' : 'js' - }` + const tsPreviewConfigPath = `${redwoodProjectPaths.storybookPreviewConfig}.tsx` + const jsPreviewConfigPath = `${redwoodProjectPaths.storybookPreviewConfig}.js` + + let userPreviewPath = './preview.example.js' + + if (fs.existsSync(tsPreviewConfigPath)) { + userPreviewPath = tsPreviewConfigPath + } else if (fs.existsSync(jsPreviewConfigPath)) { + userPreviewPath = jsPreviewConfigPath + } - const userPreviewPath = fs.existsSync(sbPreviewConfigPath) - ? sbPreviewConfigPath - : './preview.example.js' sbConfig.resolve.alias['~__REDWOOD__USER_STORYBOOK_PREVIEW_CONFIG'] = userPreviewPath From 36a032362d8977148b3a2541aa458a0cc32dc72f Mon Sep 17 00:00:00 2001 From: Boris Novikov Date: Sat, 2 Dec 2023 10:51:03 +0100 Subject: [PATCH 14/17] fix: pr --- packages/cli/src/commands/setup/ui/libraries/mantine.js | 3 ++- packages/cli/src/lib/configureStorybook.js | 7 ++++--- packages/cli/src/lib/merge/index.js | 5 ++--- packages/project-config/src/paths.ts | 7 +++---- packages/testing/config/storybook/main.js | 9 ++------- 5 files changed, 13 insertions(+), 18 deletions(-) diff --git a/packages/cli/src/commands/setup/ui/libraries/mantine.js b/packages/cli/src/commands/setup/ui/libraries/mantine.js index 1fe46d3c37ce..c77466d9bd66 100644 --- a/packages/cli/src/commands/setup/ui/libraries/mantine.js +++ b/packages/cli/src/commands/setup/ui/libraries/mantine.js @@ -158,7 +158,8 @@ export async function handler({ force, install, packages }) { }, { title: 'Configure Storybook...', - skip: () => fileIncludes(rwPaths.web.storybookConfig, 'withMantine'), + skip: () => + fileIncludes(rwPaths.web.storybookPreviewConfig, 'withMantine'), task: async () => extendStorybookConfiguration( path.join( diff --git a/packages/cli/src/lib/configureStorybook.js b/packages/cli/src/lib/configureStorybook.js index d55d7e5900d8..3f79e0abb238 100644 --- a/packages/cli/src/lib/configureStorybook.js +++ b/packages/cli/src/lib/configureStorybook.js @@ -21,10 +21,11 @@ import { getPaths, transformTSToJS, writeFile } from '.' export default async function extendStorybookConfiguration( newConfigPath = undefined ) { + const webPaths = getPaths().web const ts = isTypeScriptProject() - const sbPreviewConfigPath = `${getPaths().web.storybookPreviewConfig}.${ - ts ? 'tsx' : 'js' - }` + const sbPreviewConfigPath = + webPaths.storybookPreviewConfig ?? + `${webPaths.config}/storybook.preview.${ts ? 'tsx' : 'js'}` const read = (path) => fse.readFileSync(path, { encoding: 'utf-8' }) if (!fse.existsSync(sbPreviewConfigPath)) { diff --git a/packages/cli/src/lib/merge/index.js b/packages/cli/src/lib/merge/index.js index 35c97981294d..2c9d6989d285 100644 --- a/packages/cli/src/lib/merge/index.js +++ b/packages/cli/src/lib/merge/index.js @@ -212,9 +212,8 @@ function mergeAST(baseAST, extAST, strategy = {}) { export function merge(base, extension, strategy) { function parseReact(code) { return parse(code, { - filename: 'merge.tsx', - presets: ['@babel/preset-react', '@babel/preset-typescript'], - plugins: ['@babel/plugin-transform-typescript'], + filename: 'merged.tsx', + presets: ['@babel/preset-typescript'], }) } diff --git a/packages/project-config/src/paths.ts b/packages/project-config/src/paths.ts index e823292f7f00..ed79fb75db34 100644 --- a/packages/project-config/src/paths.ts +++ b/packages/project-config/src/paths.ts @@ -45,7 +45,7 @@ export interface WebPaths { entries: string | null postcss: string storybookConfig: string - storybookPreviewConfig: string + storybookPreviewConfig: string | null storybookManagerConfig: string dist: string distServer: string @@ -228,9 +228,8 @@ export const getPaths = (BASE_DIR: string = getBaseDir()): Paths => { BASE_DIR, PATH_WEB_DIR_CONFIG_STORYBOOK_CONFIG ), - storybookPreviewConfig: path.join( - BASE_DIR, - PATH_WEB_DIR_CONFIG_STORYBOOK_PREVIEW + storybookPreviewConfig: resolveFile( + path.join(BASE_DIR, PATH_WEB_DIR_CONFIG_STORYBOOK_PREVIEW) ), storybookManagerConfig: path.join( BASE_DIR, diff --git a/packages/testing/config/storybook/main.js b/packages/testing/config/storybook/main.js index 1b4f5b89066b..63d8017b6733 100644 --- a/packages/testing/config/storybook/main.js +++ b/packages/testing/config/storybook/main.js @@ -74,15 +74,10 @@ const baseConfig = { } } - const tsPreviewConfigPath = `${redwoodProjectPaths.storybookPreviewConfig}.tsx` - const jsPreviewConfigPath = `${redwoodProjectPaths.storybookPreviewConfig}.js` - let userPreviewPath = './preview.example.js' - if (fs.existsSync(tsPreviewConfigPath)) { - userPreviewPath = tsPreviewConfigPath - } else if (fs.existsSync(jsPreviewConfigPath)) { - userPreviewPath = jsPreviewConfigPath + if (fs.existsSync(redwoodProjectPaths.storybookPreviewConfig)) { + userPreviewPath = redwoodProjectPaths.storybookPreviewConfig } sbConfig.resolve.alias['~__REDWOOD__USER_STORYBOOK_PREVIEW_CONFIG'] = From de828f00af01bad9e2a72ea8474cf3152dab1201 Mon Sep 17 00:00:00 2001 From: Boris Novikov Date: Sat, 2 Dec 2023 10:59:06 +0100 Subject: [PATCH 15/17] fix: failing tests --- .../src/__tests__/paths.test.ts | 28 +++---------------- 1 file changed, 4 insertions(+), 24 deletions(-) diff --git a/packages/project-config/src/__tests__/paths.test.ts b/packages/project-config/src/__tests__/paths.test.ts index 0011f4c14dc1..a0245b0d1fbb 100644 --- a/packages/project-config/src/__tests__/paths.test.ts +++ b/packages/project-config/src/__tests__/paths.test.ts @@ -131,12 +131,7 @@ describe('paths', () => { 'config', 'storybook.config.js' ), - storybookPreviewConfig: path.join( - FIXTURE_BASEDIR, - 'web', - 'config', - 'storybook.preview' - ), + storybookPreviewConfig: null, storybookManagerConfig: path.join( FIXTURE_BASEDIR, 'web', @@ -411,12 +406,7 @@ describe('paths', () => { 'config', 'storybook.config.js' ), - storybookPreviewConfig: path.join( - FIXTURE_BASEDIR, - 'web', - 'config', - 'storybook.preview' - ), + storybookPreviewConfig: null, storybookManagerConfig: path.join( FIXTURE_BASEDIR, 'web', @@ -737,12 +727,7 @@ describe('paths', () => { 'config', 'storybook.config.js' ), - storybookPreviewConfig: path.join( - FIXTURE_BASEDIR, - 'web', - 'config', - 'storybook.preview' - ), + storybookPreviewConfig: null, storybookManagerConfig: path.join( FIXTURE_BASEDIR, 'web', @@ -1020,12 +1005,7 @@ describe('paths', () => { 'config', 'storybook.config.js' ), - storybookPreviewConfig: path.join( - FIXTURE_BASEDIR, - 'web', - 'config', - 'storybook.preview' - ), + storybookPreviewConfig: null, storybookManagerConfig: path.join( FIXTURE_BASEDIR, 'web', From 79ef0f01c526184dd2f278845a56136b66af8751 Mon Sep 17 00:00:00 2001 From: Boris Novikov Date: Sun, 24 Dec 2023 14:25:28 +0100 Subject: [PATCH 16/17] fix: pr suggestions --- packages/cli/src/lib/merge/index.js | 2 +- packages/testing/config/storybook/main.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/cli/src/lib/merge/index.js b/packages/cli/src/lib/merge/index.js index 2c9d6989d285..bc0637484540 100644 --- a/packages/cli/src/lib/merge/index.js +++ b/packages/cli/src/lib/merge/index.js @@ -212,7 +212,7 @@ function mergeAST(baseAST, extAST, strategy = {}) { export function merge(base, extension, strategy) { function parseReact(code) { return parse(code, { - filename: 'merged.tsx', + filename: 'merged.tsx', // required to prevent babel error. The .tsx is relevant presets: ['@babel/preset-typescript'], }) } diff --git a/packages/testing/config/storybook/main.js b/packages/testing/config/storybook/main.js index 63d8017b6733..9319ea4d5b9f 100644 --- a/packages/testing/config/storybook/main.js +++ b/packages/testing/config/storybook/main.js @@ -76,7 +76,7 @@ const baseConfig = { let userPreviewPath = './preview.example.js' - if (fs.existsSync(redwoodProjectPaths.storybookPreviewConfig)) { + if (redwoodProjectPaths.storybookPreviewConfig) { userPreviewPath = redwoodProjectPaths.storybookPreviewConfig } From a0f91f6f629aa21fe28fb85de5f5c8853bef51f1 Mon Sep 17 00:00:00 2001 From: Boris Novikov Date: Sun, 24 Dec 2023 21:39:02 +0100 Subject: [PATCH 17/17] feat: jsx/tsx/ts merge tests --- .../cli/src/lib/__tests__/mergeBasics.test.js | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/packages/cli/src/lib/__tests__/mergeBasics.test.js b/packages/cli/src/lib/__tests__/mergeBasics.test.js index 28845dbc5aef..cac630c55e73 100644 --- a/packages/cli/src/lib/__tests__/mergeBasics.test.js +++ b/packages/cli/src/lib/__tests__/mergeBasics.test.js @@ -35,6 +35,36 @@ describe('the basics', () => { { ArrayExpression: concatUnique } ) }) + it('Merges JSX strings', () => { + const componentA = 'const ComponentA = (props) =>
Hello
' + const componentB = 'const ComponentB = (props) =>
Bye
' + expectTrivialConcat(componentA, componentB) + }) + it('Merges TSX strings', () => { + const componentA = + 'const ComponentA: MyComponent = (props) =>
Hello
' + const componentB = + 'const ComponentB: MyComponent = (props) =>
Bye
' + expectTrivialConcat(componentA, componentB) + }) + it('Merges TS strings', () => { + expectMerged( + `\ + const x: string = 'x' + const list: string[] = [x] + `, + `\ + const y: string = 'y' + const list: string[] = [y] + `, + `\ + const x: string = 'x' + const y: string = 'y' + const list: string[] = [x, y] + `, + { ArrayExpression: concatUnique } + ) + }) }) describe('Import behavior', () => {