Skip to content

Commit

Permalink
Merge pull request #29002 from storybookjs/version-non-patch-from-8.3…
Browse files Browse the repository at this point in the history
….0-beta.0

Release: Prerelease 8.3.0-beta.1
  • Loading branch information
JReinhold authored Aug 30, 2024
2 parents d8b6ce8 + 288862b commit 3ff8151
Show file tree
Hide file tree
Showing 46 changed files with 218 additions and 142 deletions.
8 changes: 8 additions & 0 deletions CHANGELOG.prerelease.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
## 8.3.0-beta.1

- ConfigFile: Fix `as const satisfies` modifiers - [#29000](https://github.com/storybookjs/storybook/pull/29000), thanks @shilman!
- Core: Move `util` to regular dependency - [#29008](https://github.com/storybookjs/storybook/pull/29008), thanks @ndelangen!
- Next.js-Vite: Streamline Next.js dir option - [#28995](https://github.com/storybookjs/storybook/pull/28995), thanks @valentinpalkovic!
- Next.js: Fix wrong Next.js framework reference - [#28992](https://github.com/storybookjs/storybook/pull/28992), thanks @valentinpalkovic!
- Vue3: Add vite plugin for portable stories - [#29004](https://github.com/storybookjs/storybook/pull/29004), thanks @yannbf!

## 8.3.0-beta.0

Empty release identical to `v8.3.0-alpha.11`
Expand Down
16 changes: 13 additions & 3 deletions MIGRATION.md
Original file line number Diff line number Diff line change
Expand Up @@ -430,8 +430,12 @@ These APIs allowed addons to render arbitrary content in the Storybook sidebar.

> [!NOTE]
> You need to set the feature flag `backgroundsStoryGlobals` to `true` in your `.storybook/main.ts` to use the new format and set the value with `globals`.
>
> See here how to set feature flags: https://storybook.js.org/docs/api/main-config/main-config-features
The `addon-backgrounds` addon now uses a new format for parameters. The `backgrounds` parameter is now an object with an `options` property that is assigned to an object of background values, where the key is used when setting the global value.
The `addon-backgrounds` addon now uses a new format for configuring its list of selectable backgrounds.
The `backgrounds` parameter is now an object with an `options` property.
This `options` object is a key-value pair where the key is used when setting the global value, the value is an object with a `name` and `value` property.

```diff
// .storybook/preview.js
Expand Down Expand Up @@ -472,8 +476,13 @@ This locks that story to the `twitter` background, it cannot be changed by the a

> [!NOTE]
> You need to set the feature flag `viewportStoryGlobals` to `true` in your `.storybook/main.ts` to use the new format and set the value with `globals`.
>
> See here how to set feature flags: https://storybook.js.org/docs/api/main-config/main-config-features
The `addon-viewport` addon now uses a new format for parameters. The `viewport` parameter is now an object with an `options` property that is assigned to an object of viewport values, where the key is used when setting the global value.
The `addon-viewport` addon now uses a new format for configuring its list of selectable viewports.
The `viewport` parameter is now an object with an `options` property.
This `options` object is a key-value pair where the key is used when setting the global value, the value is an object with a `name` and `styles` property.
The `styles` property is an object with a `width` and a `height` property.

```diff
// .storybook/preview.js
Expand Down Expand Up @@ -501,7 +510,8 @@ export const parameters = {
};
```

Setting an override value should now be done via a `globals` property on your component/meta or story itself. Also note the change from `defaultOrientation: "landscape"` to `isRotated: true`.
Setting an override value should now be done via a `globals` property on your component/meta or story itself.
Also note the change from `defaultOrientation: "landscape"` to `isRotated: true`.

```diff
// Button.stories.ts
Expand Down
5 changes: 5 additions & 0 deletions code/addons/vitest/src/postinstall.ts
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,11 @@ const getVitestPluginInfo = (framework: string) => {
frameworkPluginCall = 'storybookSveltekitPlugin()';
}

if (framework === '@storybook/vue3-vite') {
frameworkPluginImport = "import { storybookVuePlugin } from '@storybook/vue3-vite/vite'";
frameworkPluginCall = 'storybookVuePlugin()';
}

return { frameworkPluginImport, frameworkPluginCall };
};

Expand Down
2 changes: 1 addition & 1 deletion code/core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -286,6 +286,7 @@
"process": "^0.11.10",
"recast": "^0.23.5",
"semver": "^7.6.2",
"util": "^0.12.5",
"ws": "^8.2.3"
},
"devDependencies": {
Expand Down Expand Up @@ -418,7 +419,6 @@
"typescript": "^5.3.2",
"unique-string": "^3.0.0",
"use-resize-observer": "^9.1.0",
"util": "^0.12.4",
"watchpack": "^2.2.0"
},
"publishConfig": {
Expand Down
20 changes: 20 additions & 0 deletions code/core/src/csf-tools/ConfigFile.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -795,6 +795,26 @@ describe('ConfigFile', () => {
export default preview;
`);
});

it('root globals as const satisfies as variable', () => {
expect(
removeField(
['globals'],
dedent`
const preview = {
globals: { a: 1 },
bar: { a: 1 }
} as const satisfies Foo;
export default preview;
`
)
).toMatchInlineSnapshot(`
const preview = {
bar: { a: 1 }
} as const satisfies Foo;
export default preview;
`);
});
});

describe('quotes', () => {
Expand Down
20 changes: 11 additions & 9 deletions code/core/src/csf-tools/ConfigFile.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,13 @@ const propKey = (p: t.ObjectProperty) => {
return null;
};

const unwrap = (node: t.Node | undefined | null): any => {
if (t.isTSAsExpression(node) || t.isTSSatisfiesExpression(node)) {
return unwrap(node.expression);
}
return node;
};

// eslint-disable-next-line @typescript-eslint/naming-convention
const _getPath = (path: string[], node: t.Node): t.Node | undefined => {
if (path.length === 0) {
Expand Down Expand Up @@ -191,9 +198,7 @@ export class ConfigFile {
? _findVarInitialization(node.declaration.name, parent)
: node.declaration;

if (t.isTSAsExpression(decl) || t.isTSSatisfiesExpression(decl)) {
decl = decl.expression;
}
decl = unwrap(decl);

if (t.isObjectExpression(decl)) {
self._exportsObject = decl;
Expand Down Expand Up @@ -275,9 +280,7 @@ export class ConfigFile {
exportObject = _findVarInitialization(right.name, parent as t.Program) as any;
}

if (t.isTSAsExpression(exportObject) || t.isTSSatisfiesExpression(exportObject)) {
exportObject = exportObject.expression;
}
exportObject = unwrap(exportObject);

if (t.isObjectExpression(exportObject)) {
self._exportsObject = exportObject;
Expand Down Expand Up @@ -517,9 +520,8 @@ export class ConfigFile {
if (t.isIdentifier(decl)) {
decl = _findVarInitialization(decl.name, this._ast.program);
}
if (t.isTSAsExpression(decl) || t.isTSSatisfiesExpression(decl)) {
decl = decl.expression;
}

decl = unwrap(decl);
if (t.isObjectExpression(decl)) {
const properties = decl.properties as t.ObjectProperty[];
removeProperty(properties, path[0]);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
// We need this import to be a singleton, and because it's used in multiple entrypoints
// both in ESM and CJS, importing it via the package name instead of having a local import
// is the only way to achieve it actually being a singleton
import { fn } from '@storybook/test';

// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore we must ignore types here as during compilation they are not generated yet
import { headers } from '@storybook/nextjs/headers.mock';
import { fn } from '@storybook/test';
import { headers } from '@storybook/experimental-nextjs-vite/headers.mock';

import { RequestCookies } from 'next/dist/compiled/@edge-runtime/cookies';

Expand Down
16 changes: 7 additions & 9 deletions code/frameworks/experimental-nextjs-vite/src/preset.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
// https://storybook.js.org/docs/react/addons/writing-presets
import path from 'node:path';

import type { PresetProperty } from 'storybook/internal/types';

import type { StorybookConfigVite } from '@storybook/builder-vite';
Expand All @@ -7,7 +9,7 @@ import { dirname, join } from 'path';
// @ts-expect-error - tsconfig settings have to be moduleResolution=Bundler and module=Preserve
import vitePluginStorybookNextjs from 'vite-plugin-storybook-nextjs';

import type { StorybookConfig } from './types';
import type { FrameworkOptions } from './types';

export const core: PresetProperty<'core'> = async (config, options) => {
const framework = await options.presets.apply('framework');
Expand All @@ -34,14 +36,10 @@ export const previewAnnotations: PresetProperty<'previewAnnotations'> = (entry =

export const viteFinal: StorybookConfigVite['viteFinal'] = async (config, options) => {
config.plugins = config.plugins || [];
const framework = (await options.presets.apply(
'framework',
{},
options
)) as StorybookConfig['framework'];

const nextAppDir = typeof framework !== 'string' ? framework.options.nextAppDir : undefined;
config.plugins.push(vitePluginStorybookNextjs({ dir: nextAppDir }));
const { nextConfigPath } = await options.presets.apply<FrameworkOptions>('frameworkOptions');

const nextDir = nextConfigPath ? path.dirname(nextConfigPath) : undefined;
config.plugins.push(vitePluginStorybookNextjs({ dir: nextDir }));

return config;
};
8 changes: 2 additions & 6 deletions code/frameworks/experimental-nextjs-vite/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,8 @@ type FrameworkName = CompatibleString<'@storybook/experimental-nextjs-vite'>;
type BuilderName = CompatibleString<'@storybook/builder-vite'>;

export type FrameworkOptions = {
/**
* The directory where the Next.js app is located.
*
* @default process.cwd()
*/
nextAppDir?: string;
/** The path to the Next.js configuration file. */
nextConfigPath?: string;
builder?: BuilderOptions;
};

Expand Down
1 change: 0 additions & 1 deletion code/frameworks/nextjs/src/preview.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import type { Addon_DecoratorFunction, Addon_LoaderFunction } from 'storybook/in
// is the only way to achieve it actually being a singleton
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore we must ignore types here as during compilation they are not generated yet
import { cookies, headers } from '@storybook/nextjs/headers.mock';
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore we must ignore types here as during compilation they are not generated yet
import { createNavigation } from '@storybook/nextjs/navigation.mock';
Expand Down
8 changes: 7 additions & 1 deletion code/frameworks/vue3-vite/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,11 @@
"types": "./dist/preset.d.ts",
"require": "./dist/preset.js"
},
"./vite": {
"types": "./dist/vite.d.ts",
"require": "./dist/vite.js",
"import": "./dist/vite.mjs"
},
"./package.json": "./package.json"
},
"main": "dist/index.js",
Expand Down Expand Up @@ -74,7 +79,8 @@
"bundler": {
"entries": [
"./src/index.ts",
"./src/preset.ts"
"./src/preset.ts",
"./src/vite.ts"
],
"platform": "node"
},
Expand Down
14 changes: 14 additions & 0 deletions code/frameworks/vue3-vite/src/plugins/vue-template.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import type { Plugin } from 'vite';

export async function templateCompilation() {
return {
name: 'storybook:vue-template-compilation',
config: () => ({
resolve: {
alias: {
vue: 'vue/dist/vue.esm-bundler.js',
},
},
}),
} satisfies Plugin;
}
8 changes: 2 additions & 6 deletions code/frameworks/vue3-vite/src/preset.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import type { PluginOption } from 'vite';

import { vueComponentMeta } from './plugins/vue-component-meta';
import { vueDocgen } from './plugins/vue-docgen';
import { templateCompilation } from './plugins/vue-template';
import type { FrameworkOptions, StorybookConfig, VueDocgenPlugin } from './types';

const getAbsolutePath = <I extends string>(input: I): I =>
Expand All @@ -17,7 +18,7 @@ export const core: PresetProperty<'core'> = {
};

export const viteFinal: StorybookConfig['viteFinal'] = async (config, options) => {
const plugins: PluginOption[] = [];
const plugins: PluginOption[] = [templateCompilation()];

const framework = await options.presets.apply('framework');
const frameworkOptions: FrameworkOptions =
Expand All @@ -35,11 +36,6 @@ export const viteFinal: StorybookConfig['viteFinal'] = async (config, options) =
const { mergeConfig } = await import('vite');
return mergeConfig(config, {
plugins,
resolve: {
alias: {
vue: 'vue/dist/vue.esm-bundler.js',
},
},
});
};

Expand Down
5 changes: 5 additions & 0 deletions code/frameworks/vue3-vite/src/vite.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { templateCompilation } from './plugins/vue-template';

export const storybookVuePlugin = () => {
return [templateCompilation()];
};
3 changes: 2 additions & 1 deletion code/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -294,5 +294,6 @@
"Dependency Upgrades"
]
]
}
},
"deferredNextVersion": "8.3.0-beta.1"
}
2 changes: 1 addition & 1 deletion code/yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -6034,7 +6034,7 @@ __metadata:
typescript: "npm:^5.3.2"
unique-string: "npm:^3.0.0"
use-resize-observer: "npm:^9.1.0"
util: "npm:^0.12.4"
util: "npm:^0.12.5"
watchpack: "npm:^2.2.0"
ws: "npm:^8.2.3"
languageName: unknown
Expand Down
2 changes: 1 addition & 1 deletion docs/api/doc-blocks/doc-block-story.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ Because all stories render simultaneously in docs entries, play functions can pe
However, if you know your play function is “safe” to run in docs, you can use this prop to run it automatically.

<Callout variant="info">
If a story uses [`mount` in its play function](../../writing-tests/interaction-testing.mdx#run-code-before-the-component-gets-rendered), it will not render in docs unless `autoplay` is set to `true`.
If a story uses [`mount` in its play function](../../writing-tests/component-testing.mdx#run-code-before-the-component-gets-rendered), it will not render in docs unless `autoplay` is set to `true`.
</Callout>

### `height`
Expand Down
4 changes: 2 additions & 2 deletions docs/api/portable-stories/portable-stories-jest.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@ sidebar:
These are the configurations needed in the setup file:
- preview annotations: those defined in `.storybook/preview.ts`
- addon annotations (optional): those exported by addons
- beforeAll: code that runs before all tests ([more info](../../writing-tests/interaction-testing.mdx#beforeall))
- beforeAll: code that runs before all tests ([more info](../../writing-tests/component-testing.mdx#beforeall))

{/* prettier-ignore-start */}

Expand Down Expand Up @@ -222,7 +222,7 @@ sidebar:

### 3. Run

Finally, stories can prepare data they need (e.g. setting up some mocks or fetching data) before rendering by defining [loaders](../../writing-stories/loaders.mdx), [beforeEach](../../writing-tests/interaction-testing.mdx#run-code-before-each-story) or by having all the story code in the play function when using the [mount](../../writing-tests/interaction-testing.mdx#run-code-before-the-component-gets-rendered). In portable stories, all of these steps will be executed when you call the `run` method of the composed story.
Finally, stories can prepare data they need (e.g. setting up some mocks or fetching data) before rendering by defining [loaders](../../writing-stories/loaders.mdx), [beforeEach](../../writing-tests/component-testing.mdx#run-code-before-each-story) or by having all the story code in the play function when using the [mount](../../writing-tests/component-testing.mdx#run-code-before-the-component-gets-rendered). In portable stories, all of these steps will be executed when you call the `run` method of the composed story.

👉 For this, you use the [`composeStories`](#composestories) or [`composeStory`](#composestory) API. The composed story will return a `run` method to be called.

Expand Down
2 changes: 1 addition & 1 deletion docs/api/portable-stories/portable-stories-playwright.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ sidebar:
These are the configurations needed in the setup file:
- preview annotations: those defined in `.storybook/preview.ts`
- addon annotations (optional): those exported by addons
- beforeAll: code that runs before all tests ([more info](../../writing-tests/interaction-testing.mdx#beforeall))
- beforeAll: code that runs before all tests ([more info](../../writing-tests/component-testing.mdx#beforeall))

{/* prettier-ignore-start */}

Expand Down
4 changes: 2 additions & 2 deletions docs/api/portable-stories/portable-stories-vitest.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ sidebar:
These are the configurations needed in the setup file:
- preview annotations: those defined in `.storybook/preview.ts`
- addon annotations (optional): those exported by addons
- beforeAll: code that runs before all tests ([more info](../../writing-tests/interaction-testing.mdx#beforeall))
- beforeAll: code that runs before all tests ([more info](../../writing-tests/component-testing.mdx#beforeall))

{/* prettier-ignore-start */}

Expand Down Expand Up @@ -230,7 +230,7 @@ sidebar:

### 3. Run

Finally, stories can prepare data they need (e.g. setting up some mocks or fetching data) before rendering by defining [loaders](../../writing-stories/loaders.mdx), [beforeEach](../../writing-tests/interaction-testing.mdx#run-code-before-each-story) or by having all the story code in the play function when using the [mount](../../writing-tests/interaction-testing.mdx#run-code-before-the-component-gets-rendered). In portable stories, all of these steps will be executed when you call the `run` method of the composed story.
Finally, stories can prepare data they need (e.g. setting up some mocks or fetching data) before rendering by defining [loaders](../../writing-stories/loaders.mdx), [beforeEach](../../writing-tests/component-testing.mdx#run-code-before-each-story) or by having all the story code in the play function when using the [mount](../../writing-tests/component-testing.mdx#run-code-before-the-component-gets-rendered). In portable stories, all of these steps will be executed when you call the `run` method of the composed story.

👉 For this, you use the [`composeStories`](#composestories) or [`composeStory`](#composestory) API. The composed story will return a `run` method to be called.

Expand Down
4 changes: 2 additions & 2 deletions docs/builders/vite.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -97,9 +97,9 @@ Currently, [automatic argType inference](../api/arg-types.mdx#automatic-argtype-

{/* prettier-ignore-end */}

### Interaction tests not working as expected
### Component tests not working as expected

If you are migrating from a Webpack-based project, such as [CRA](https://create-react-app.dev/), to Vite, and you have enabled Interaction testing with the [`@storybook/addon-interactions`](https://storybook.js.org/addons/@storybook/addon-interactions) addon, you may run into a situation where your tests fail to execute notifying you that the `window` object is not defined. To resolve this issue, you can create a `preview-head.html` file in your Storybook configuration directory and include the following:
If you are migrating from a Webpack-based project, such as [CRA](https://create-react-app.dev/), to Vite, and you have enabled component testing with the [`@storybook/addon-interactions`](https://storybook.js.org/addons/@storybook/addon-interactions) addon, you may run into a situation where your tests fail to execute notifying you that the `window` object is not defined. To resolve this issue, you can create a `preview-head.html` file in your Storybook configuration directory and include the following:

{/* prettier-ignore-start */}

Expand Down
Loading

0 comments on commit 3ff8151

Please sign in to comment.