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

+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) => {