diff --git a/CHANGELOG.md b/CHANGELOG.md index 1ca691693f51..bc9fd2b3e316 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,8 @@ +## 10.1.11 + +- React: Fix several CSF factory bugs - [#33354](https://github.com/storybookjs/storybook/pull/33354), thanks @kasperpeulen! +- UI: Fix React error 300 on some addons - [#33381](https://github.com/storybookjs/storybook/pull/33381), thanks @Sidnioulz! + ## 10.1.10 - Core: Fix `.env`-file parsing - [#33383](https://github.com/storybookjs/storybook/pull/33383), thanks @JReinhold! @@ -297,10 +302,6 @@ It also includes features to level up your UI development, documentation, and te -## 9.1.17 - -- Core: Fix .env-file parsing, thanks @jreinhold! - ## 9.1.16 - CLI: Fix Nextjs project creation in empty directories - [#32828](https://github.com/storybookjs/storybook/pull/32828), thanks @yannbf! @@ -846,10 +847,6 @@ Unique contributors: 29 -## 8.6.15 - -- Core: Fix .env-file parsing, thanks @jreinhold! - ## 8.6.14 - CLI: Add skip onboarding, recommended/minimal config - [#30930](https://github.com/storybookjs/storybook/pull/30930), thanks @shilman! @@ -1827,10 +1824,6 @@ It brings major improvements to Storybook's feature set for testing and document Please checkout our [Migration Guide](https://storybook.js.org/docs/8.0/migration-guide) to upgrade from earlier versions of Storybook. To see a comprehensive list of changes that went into 8.0, you can refer to the [8.0 prerelease changelogs](https://github.com/storybookjs/storybook/blob/next/CHANGELOG.prerelease.md). -## 7.6.21 - -- Core: Fix .env-file parsing, thanks @jreinhold! - ## 7.6.17 - Addon-docs: Fix Table of Contents heading leak - [#23677](https://github.com/storybookjs/storybook/pull/23677), thanks [@vmizg](https://github.com/vmizg)! diff --git a/CHANGELOG.prerelease.md b/CHANGELOG.prerelease.md index 669af7ba4be0..ada2157213bd 100644 --- a/CHANGELOG.prerelease.md +++ b/CHANGELOG.prerelease.md @@ -1,3 +1,8 @@ +## 10.2.0-alpha.11 + +- Core: Add try-catch for cross-origin access in Storybook hooks - [#33448](https://github.com/storybookjs/storybook/pull/33448), thanks @ndelangen! +- UI: Keep preview frame stable in overall layout - [#33447](https://github.com/storybookjs/storybook/pull/33447), thanks @Sidnioulz! + ## 10.2.0-alpha.10 - Dependencies: Bump various packages - [#33412](https://github.com/storybookjs/storybook/pull/33412), thanks @ndelangen! diff --git a/code/core/src/manager/components/layout/Layout.tsx b/code/core/src/manager/components/layout/Layout.tsx index be3f3ee054de..4398df3c5c89 100644 --- a/code/core/src/manager/components/layout/Layout.tsx +++ b/code/core/src/manager/components/layout/Layout.tsx @@ -169,39 +169,35 @@ export const Layout = ({ managerLayoutState, setManagerLayoutState, hasTab, ...s showPanel={showPanel} > {showPages && {slots.slotPages}} - {isDesktop && ( - <> + <> + {isDesktop && ( {slots.slotSidebar} - - {slots.slotMain} - - {showPanel && ( - - - {slots.slotPanel} - - )} - - )} - - {isMobile && ( - <> + )} + {isMobile && ( - {slots.slotMain} - - - )} + )} + + {slots.slotMain} + + {isDesktop && showPanel && ( + + + {slots.slotPanel} + + )} + {isMobile && } + ); }; diff --git a/code/core/template/stories/preview.ts b/code/core/template/stories/preview.ts index 3756bc7d73cb..106b8844edc3 100644 --- a/code/core/template/stories/preview.ts +++ b/code/core/template/stories/preview.ts @@ -9,15 +9,30 @@ declare global { } } -// This is used to test the hooks in our E2E tests (look for storybook-hooks.spec.ts) -globalThis.parent.__STORYBOOK_BEFORE_ALL_CALLS__ = 0; -globalThis.parent.__STORYBOOK_BEFORE_ALL_CLEANUP_CALLS__ = 0; +try { + // This is used to test the hooks in our E2E tests (look for storybook-hooks.spec.ts) + + /** + * Wrapped in a try-catch, because accessing properties on globalThis.parent may throw if the + * parent is cross-origin. + */ + globalThis.parent.__STORYBOOK_BEFORE_ALL_CALLS__ = 0; + globalThis.parent.__STORYBOOK_BEFORE_ALL_CLEANUP_CALLS__ = 0; +} catch { + // ignore +} export const beforeAll = async () => { - globalThis.parent.__STORYBOOK_BEFORE_ALL_CALLS__ += 1; - return () => { - globalThis.parent.__STORYBOOK_BEFORE_ALL_CLEANUP_CALLS__ += 1; - }; + let cleanup: () => void = () => {}; + try { + globalThis.parent.__STORYBOOK_BEFORE_ALL_CALLS__ += 1; + cleanup = () => { + globalThis.parent.__STORYBOOK_BEFORE_ALL_CLEANUP_CALLS__ += 1; + }; + } catch { + // ignore + } + return cleanup; }; export const parameters = { diff --git a/code/package.json b/code/package.json index 8def4d577473..9b6176664c31 100644 --- a/code/package.json +++ b/code/package.json @@ -220,5 +220,6 @@ "Dependency Upgrades" ] ] - } + }, + "deferredNextVersion": "10.2.0-alpha.11" } diff --git a/docs/api/main-config/main-config-static-dirs.mdx b/docs/api/main-config/main-config-static-dirs.mdx index 5b026d11a370..0207e0b5e67d 100644 --- a/docs/api/main-config/main-config-static-dirs.mdx +++ b/docs/api/main-config/main-config-static-dirs.mdx @@ -17,6 +17,10 @@ Sets a list of directories of [static files](../../configure/integration/images- {/* prettier-ignore-end */} + +When using Vite-based frameworks, additional directories may be copied to your build directory because of Vite's own [static asset handling](https://vite.dev/guide/assets#the-public-directory). You can set Vite's `publicDir` option to `false` to disable this behavior. + + ## With configuration objects You can also use a configuration object to define the directories: @@ -25,4 +29,4 @@ You can also use a configuration object to define the directories: -{/* prettier-ignore-end */} +{/* prettier-ignore-end */} \ No newline at end of file diff --git a/docs/configure/integration/images-and-assets.mdx b/docs/configure/integration/images-and-assets.mdx index 8670b6e41939..757d858c68ae 100644 --- a/docs/configure/integration/images-and-assets.mdx +++ b/docs/configure/integration/images-and-assets.mdx @@ -55,6 +55,10 @@ Or even use a configuration object to define the directories: {/* prettier-ignore-end */} + +When using Vite-based frameworks, additional directories may be copied to your build directory because of Vite's own [static asset handling](https://vite.dev/guide/assets#the-public-directory). You can set Vite's `publicDir` option to `false` to disable this behavior. + + ## Reference assets from a CDN Upload your files to an online CDN and reference them. In this example, we’re using a placeholder image service. diff --git a/docs/contribute/code.mdx b/docs/contribute/code.mdx index c02ba28efbac..fe23efbcb59a 100644 --- a/docs/contribute/code.mdx +++ b/docs/contribute/code.mdx @@ -102,6 +102,19 @@ Otherwise, if it affects the `Manager` (the outermost Storybook `iframe` where t ![Storybook manager preview](../_assets/addons/manager-preview.png) +The `yarn build` commands accepts arguments to help speed up your development workflow: +* `--all` will cause all packages to be built +* `--watch` will enable watch mode (and skip the watch mode prompt) +* `--prod` will build for production (and skip the production mode prompt) +* individual package names can be passed, without the `@storybook/` prefix, e.g. `storybook`, `addon-docs`, etc. + +For example, to build Storybook and the docs addon in watch mode, run: + +```shell +yarn build --watch storybook addon-docs +``` + + ## Check your work When you're done coding, add documentation and tests as appropriate. That simplifies the PR review process, which means your code will get merged faster. diff --git a/docs/versions/next.json b/docs/versions/next.json index 93a5b271a37b..c5c0e540568c 100644 --- a/docs/versions/next.json +++ b/docs/versions/next.json @@ -1 +1 @@ -{"version":"10.2.0-alpha.10","info":{"plain":"- Dependencies: Bump various packages - [#33412](https://github.com/storybookjs/storybook/pull/33412), thanks @ndelangen!\n- Interactions: Add disable parameter for interactions panel - [#33368](https://github.com/storybookjs/storybook/pull/33368), thanks @jeevikar14!\n- Interactions: Fix state reset bug when switching stories with date mocks - [#33388](https://github.com/storybookjs/storybook/pull/33388), thanks @Sidnioulz!\n- Manifests: Refactor from `componentManifestGenerator` to extensible `manifests` preset property - [#33392](https://github.com/storybookjs/storybook/pull/33392), thanks @JReinhold!\n- Manifests: Support `!manifest` tag in preview files - [#33406](https://github.com/storybookjs/storybook/pull/33406), thanks @JReinhold!\n- NextJS: Import `next/dist` with `.js`-extension for ESM compat - [#33380](https://github.com/storybookjs/storybook/pull/33380), thanks @yue4u!\n- Preview: Treat canceled animations as finished - [#32401](https://github.com/storybookjs/storybook/pull/32401), thanks @bawjensen!\n- UI: Ensure consistent right padding in TreeNode - [#33322](https://github.com/storybookjs/storybook/pull/33322), thanks @Sidnioulz!\n- UI: Fix React error 300 on some addons - [#33381](https://github.com/storybookjs/storybook/pull/33381), thanks @Sidnioulz!\n- UI: Prevent primary story from duplicating anchor ID - [#33384](https://github.com/storybookjs/storybook/pull/33384), thanks @Sidnioulz!\n- Upgrade: Preserve package.json indentation when upgrading - [#32280](https://github.com/storybookjs/storybook/pull/32280), thanks @y-hsgw!\n- Vitest: Fallback detecting vitest version in postinstall - [#33415](https://github.com/storybookjs/storybook/pull/33415), thanks @ndelangen!"}} \ No newline at end of file +{"version":"10.2.0-alpha.11","info":{"plain":"- Core: Add try-catch for cross-origin access in Storybook hooks - [#33448](https://github.com/storybookjs/storybook/pull/33448), thanks @ndelangen!\n- UI: Keep preview frame stable in overall layout - [#33447](https://github.com/storybookjs/storybook/pull/33447), thanks @Sidnioulz!"}} \ No newline at end of file diff --git a/scripts/build-package.ts b/scripts/build-package.ts index 6f25888a42d0..39ec50244a95 100644 --- a/scripts/build-package.ts +++ b/scripts/build-package.ts @@ -5,9 +5,9 @@ * * You can pass a list of package names to build, or use the `--all` flag to build all packages. * - * You can also pass the `--watch` flag to build in watch mode. + * Pass the `--watch` flag to build in watch mode or `--no-watch` to skip the watch mode prompt. * - * You can also pass the `--prod` flag to build in production mode. + * Pass the `--prod` flag to build in production mode or `--no-prod` to skip the production prompt. * * When you pass no package names, you will be prompted to select which packages to build. */ @@ -25,8 +25,20 @@ import { findMostMatchText } from './utils/diff'; import { getCodeWorkspaces } from './utils/workspace'; async function run() { - const packages = (await getCodeWorkspaces()).filter(({ name }) => name !== '@storybook/code'); - const packageTasks = packages + const packages = (await getCodeWorkspaces()) + .filter(({ name }) => name !== '@storybook/code') + .sort((a) => (a.name === 'storybook' ? -1 : 0)); // Place main package first in option list + + const tasks: Record< + string, + { + name: string; + defaultValue: boolean; + suffix: string; + value?: unknown; + location?: string; + } + > = packages .map((pkg) => { let suffix = pkg.name.replace('@storybook/', ''); if (pkg.name === '@storybook/cli') { @@ -36,7 +48,6 @@ async function run() { ...pkg, suffix, defaultValue: false, - helpText: `build only the ${pkg.name} package`, }; }) .reduce( @@ -44,86 +55,59 @@ async function run() { acc[next.name] = next; return acc; }, - {} as Record< - string, - { name: string; defaultValue: boolean; suffix: string; helpText: string } - > + {} as Record ); - const tasks: Record< - string, - { - name: string; - defaultValue: boolean; - suffix: string; - helpText: string; - value?: any; - location?: string; - } - > = { - watch: { - name: `watch`, - defaultValue: false, - suffix: '--watch', - helpText: 'build on watch mode', - }, - prod: { - name: `prod`, - defaultValue: false, - suffix: '--prod', - helpText: 'build on production mode', - }, - ...packageTasks, - }; - const main = program .version('5.0.0') - .option('--all', `build everything ${picocolors.gray('(all)')}`); + .allowExcessArguments(true) + .option('--all', `build everything ${picocolors.gray('(all)')}`, false) + .option('--watch', `build in watch mode`) + .option('--prod', `build in production mode`) + .option('--no-watch', `do not build in watch mode`) + .option('--no-prod', `do not build in production mode`); + + main.parse(process.argv); - Object.keys(tasks) - .reduce((acc, key) => acc.option(tasks[key].suffix, tasks[key].helpText), main) - .parse(process.argv); + const opts = main.opts(); + let watchMode = opts.watch; + let prodMode = opts.prod; Object.keys(tasks).forEach((key) => { - const opts = program.opts(); - // checks if a flag is passed e.g. yarn build --@storybook/addon-docs --watch - const containsFlag = program.args.includes(tasks[key].suffix); + // checks if a flag is passed e.g. yarn build addon-docs --watch + const containsFlag = main.args.includes(tasks[key].suffix); tasks[key].value = containsFlag || opts.all; }); - let watchMode = process.argv.includes('--watch'); - let prodMode = process.argv.includes('--prod'); - let selection = Object.keys(tasks) - .map((key) => tasks[key]) - .filter((item) => !['watch', 'prod'].includes(item.name) && item.value === true); - - // user has passed invalid package name(s) - try to guess the correct package name(s) - if ((!selection.length && main.args.length >= 1) || selection.length !== main.args.length) { - const suffixList = Object.values(tasks) - .filter((t) => t.name.includes('@storybook')) - .map((t) => t.suffix); - - for (const arg of main.args) { - if (!suffixList.includes(arg)) { - const matchText = findMostMatchText(suffixList, arg); - - if (matchText) { - console.log( - `${picocolors.red('Error')}: ${picocolors.cyan( - arg - )} is not a valid package name, Did you mean ${picocolors.cyan(matchText)}?` - ); - } + let selection = Object.values(tasks).filter((item) => item.value === true); + + // check for invalid package name(s) and try to guess the correct package name(s) + const suffixList = Object.values(tasks).map((t) => t.suffix); + let hasInvalidName = false; + + for (const arg of main.args) { + if (!suffixList.includes(arg)) { + const matchText = findMostMatchText(suffixList, arg); + + if (matchText) { + hasInvalidName = true; + process.stderr.write( + `${picocolors.red('Error')}: ${picocolors.cyan( + arg + )} is not a valid package name, Did you mean ${picocolors.cyan(matchText)}?\n` + ); } } + } - process.exit(0); + if (hasInvalidName) { + process.exit(1); } if (!selection.length) { selection = await prompts( [ - { + watchMode === undefined && { type: 'toggle', name: 'watch', message: 'Start in watch mode', @@ -131,7 +115,7 @@ async function run() { active: 'yes', inactive: 'no', }, - { + prodMode === undefined && { type: 'toggle', name: 'prod', message: 'Start in production mode', @@ -144,7 +128,7 @@ async function run() { message: 'Select the packages to build', name: 'todo', min: 1, - hint: 'You can also run directly with package name like `yarn build core`, or `yarn build --all` for all packages!', + hint: 'You can also run directly with package name like `yarn build storybook`, or `yarn build --all` for all packages!', // @ts-expect-error @types incomplete optionsPerPage: windowSize.height - 3, // 3 lines for extra info choices: packages.map(({ name: key }) => ({ @@ -162,7 +146,7 @@ async function run() { }); } - console.log('Building selected packages...'); + process.stdout.write('Building selected packages...\n'); let lastName = ''; selection.forEach(async (v) => {