Merge branch 'next' into norbert/upgrades-2025-02-11

This commit is contained in:
Norbert de Langen 2025-02-24 15:30:13 +01:00
commit fa4fe8b659
168 changed files with 1626 additions and 1115 deletions

View File

@ -635,6 +635,7 @@ jobs:
command: |
cd code
yarn local-registry --open &
yarn wait-on tcp:127.0.0.1:6001
cd ../../
mkdir features-1
cd features-1

View File

@ -1,3 +1,13 @@
## 8.5.8
- Core: Support `esbuild@^0.25` - [#30574](https://github.com/storybookjs/storybook/pull/30574), thanks @JReinhold!
## 8.5.7
- Tags: Add story/meta usage telemetry - [#30555](https://github.com/storybookjs/storybook/pull/30555), thanks @shilman!
- Telemetry: Don't count example stories towards CSF feature stats - [#30561](https://github.com/storybookjs/storybook/pull/30561), thanks @shilman!
- Vite: Fix not stripping all HMR boundaries - [#30562](https://github.com/storybookjs/storybook/pull/30562), thanks @JReinhold!
## 8.5.6
- Builder-Vite: Fix defaulting to allowing all hosts - [#30523](https://github.com/storybookjs/storybook/pull/30523), thanks @JReinhold!

View File

@ -1,3 +1,46 @@
## 8.6.0-beta.8
- Addon-Test: Fix console error in build mode - [#30625](https://github.com/storybookjs/storybook/pull/30625), thanks @JReinhold!
- Manager: Fix panel reactivity - [#30638](https://github.com/storybookjs/storybook/pull/30638), thanks @valentinpalkovic!
## 8.6.0-beta.7
- Angular: Fix @angular/platform-browser/animations never available - [#30618](https://github.com/storybookjs/storybook/pull/30618), thanks @valentinpalkovic!
- Angular: Fix @angular/platform-browser/animations never available - [#30619](https://github.com/storybookjs/storybook/pull/30619), thanks @valentinpalkovic!
- CLI: Fix peer dep issues for npm users during upgrade - [#30616](https://github.com/storybookjs/storybook/pull/30616), thanks @valentinpalkovic!
## 8.6.0-beta.6
- CLI: Fix printing of selected features - [#30605](https://github.com/storybookjs/storybook/pull/30605), thanks @ghengeveld!
- CLI: Remove Storybook dependencies before adding re-adding them - [#30600](https://github.com/storybookjs/storybook/pull/30600), thanks @valentinpalkovic!
## 8.6.0-beta.5
- Addon-Test: Make sure that only one global portable story config is ever loaded - [#30582](https://github.com/storybookjs/storybook/pull/30582), thanks @kasperpeulen!
- Angular: Support v19.2 when @angular/animations is not installed - [#30611](https://github.com/storybookjs/storybook/pull/30611), thanks @valentinpalkovic!
- Builder-Vite: Fix runtime and iframe 404 on first load - [#30567](https://github.com/storybookjs/storybook/pull/30567), thanks @valentinpalkovic!
- CLI: Don't initially select Documentation and Testing features - [#30599](https://github.com/storybookjs/storybook/pull/30599), thanks @ghengeveld!
- CLI: Make telemetry data an object - [#30581](https://github.com/storybookjs/storybook/pull/30581), thanks @ndelangen!
- Core: Support `esbuild@^0.25` - [#30574](https://github.com/storybookjs/storybook/pull/30574), thanks @JReinhold!
- Test addon: Only update `vitest.config.ts` with workspaces, otherwise create `vitest.workspace.ts` - [#30583](https://github.com/storybookjs/storybook/pull/30583), thanks @ghengeveld!
## 8.6.0-beta.4
- Addon-Test: Add telemetry data for Focused Tests - [#30568](https://github.com/storybookjs/storybook/pull/30568), thanks @JReinhold!
- Core: Allow empty render functions in CSF factories - [#30565](https://github.com/storybookjs/storybook/pull/30565), thanks @kasperpeulen!
- Core: Fix undeclared internal dependencies - [#30566](https://github.com/storybookjs/storybook/pull/30566), thanks @kasperpeulen!
## 8.6.0-beta.3
- Addon-A11y: Fix preset loading when loaded via getAbsolutePath - [#30563](https://github.com/storybookjs/storybook/pull/30563), thanks @valentinpalkovic!
- Essentials: Fix `addon-essentials` not working when used with `getAbsolutePath` - [#30557](https://github.com/storybookjs/storybook/pull/30557), thanks @JReinhold!
- Vite: Fix not stripping all HMR boundaries - [#30562](https://github.com/storybookjs/storybook/pull/30562), thanks @JReinhold!
## 8.6.0-beta.2
- CLI: Reimplement features prompt logic to handle `--yes` and fix `--features` - [#30534](https://github.com/storybookjs/storybook/pull/30534), thanks @ghengeveld!
- Telemetry: Don't count example stories towards CSF feature stats - [#30561](https://github.com/storybookjs/storybook/pull/30561), thanks @shilman!
## 8.6.0-beta.1
- Builder-Vite: Fix defaulting to allowing all hosts - [#30523](https://github.com/storybookjs/storybook/pull/30523), thanks @JReinhold!

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/addon-a11y",
"version": "8.6.0-beta.1",
"version": "8.6.0-beta.8",
"description": "Test component compliance with web accessibility standards",
"keywords": [
"a11y",

View File

@ -1 +1 @@
import './dist/preview';
export * from './dist/preview';

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/addon-actions",
"version": "8.6.0-beta.1",
"version": "8.6.0-beta.8",
"description": "Get UI feedback when an action is performed on an interactive element",
"keywords": [
"storybook",

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/addon-backgrounds",
"version": "8.6.0-beta.1",
"version": "8.6.0-beta.8",
"description": "Switch backgrounds to view components in different settings",
"keywords": [
"addon",

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/addon-controls",
"version": "8.6.0-beta.1",
"version": "8.6.0-beta.8",
"description": "Interact with component inputs dynamically in the Storybook UI",
"keywords": [
"addon",

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/addon-docs",
"version": "8.6.0-beta.1",
"version": "8.6.0-beta.8",
"description": "Document component usage and properties in Markdown",
"keywords": [
"addon",

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/addon-essentials",
"version": "8.6.0-beta.1",
"version": "8.6.0-beta.8",
"description": "Curated addons to bring out the best of Storybook",
"keywords": [
"addon",
@ -27,7 +27,7 @@
"import": "./dist/index.mjs",
"require": "./dist/index.js"
},
"./preview": {
"./entry-preview": {
"types": "./dist/preview.d.ts",
"import": "./dist/preview.mjs",
"require": "./dist/preview.js"
@ -88,7 +88,7 @@
"*": [
"dist/index.d.ts"
],
"preview": [
"entry-preview": [
"dist/preview.d.ts"
]
}

View File

@ -0,0 +1 @@
module.exports = require('./dist/preset');

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/addon-mdx-gfm",
"version": "8.6.0-beta.1",
"version": "8.6.0-beta.8",
"description": "GitHub Flavored Markdown in Storybook",
"keywords": [
"addon",

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/addon-highlight",
"version": "8.6.0-beta.1",
"version": "8.6.0-beta.8",
"description": "Highlight DOM nodes within your stories",
"keywords": [
"storybook-addons",

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/addon-interactions",
"version": "8.6.0-beta.1",
"version": "8.6.0-beta.8",
"description": "Automate, test and debug user interactions",
"keywords": [
"storybook-addons",

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/addon-jest",
"version": "8.6.0-beta.1",
"version": "8.6.0-beta.8",
"description": "React storybook addon that show component jest report",
"keywords": [
"addon",

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/addon-links",
"version": "8.6.0-beta.1",
"version": "8.6.0-beta.8",
"description": "Link stories together to build demos and prototypes with your UI components",
"keywords": [
"storybook-addons",

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/addon-measure",
"version": "8.6.0-beta.1",
"version": "8.6.0-beta.8",
"description": "Inspect layouts by visualizing the box model",
"keywords": [
"storybook-addons",

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/addon-onboarding",
"version": "8.6.0-beta.1",
"version": "8.6.0-beta.8",
"description": "Storybook Addon Onboarding - Introduces a new onboarding experience",
"keywords": [
"storybook-addons",

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/addon-outline",
"version": "8.6.0-beta.1",
"version": "8.6.0-beta.8",
"description": "Outline all elements with CSS to help with layout placement and alignment",
"keywords": [
"storybook-addons",

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/addon-storysource",
"version": "8.6.0-beta.1",
"version": "8.6.0-beta.8",
"description": "View a storys source code to see how it works and paste into your app",
"keywords": [
"addon",

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/experimental-addon-test",
"version": "8.6.0-beta.1",
"version": "8.6.0-beta.8",
"description": "Integrate Vitest with Storybook",
"keywords": [
"storybook-addons",

View File

@ -2,4 +2,7 @@ import { experimental_UniversalStore } from 'storybook/internal/manager-api';
import { type StoreState, storeOptions } from './constants';
export const store = experimental_UniversalStore.create<StoreState>(storeOptions);
export const store = experimental_UniversalStore.create<StoreState>({
...storeOptions,
leader: (globalThis as any).CONFIG_TYPE === 'PRODUCTION',
});

View File

@ -17,6 +17,8 @@ import { VitestManager } from './vitest-manager';
export class TestManager {
vitestManager: VitestManager;
selectedStoryCountForLastRun = 0;
constructor(
private channel: Channel,
public store: experimental_UniversalStore<StoreState>,
@ -96,6 +98,8 @@ export class TestManager {
await this.vitestManager.vitestRestartPromise;
}
this.selectedStoryCountForLastRun = payload.storyIds?.length ?? 0;
await this.vitestManager.runTests(payload);
if (temporarilyDisableCoverage) {
@ -120,7 +124,20 @@ export class TestManager {
}
async sendProgressReport(payload: TestingModuleProgressReportPayload) {
this.channel.emit(TESTING_MODULE_PROGRESS_REPORT, payload);
this.channel.emit(TESTING_MODULE_PROGRESS_REPORT, {
...payload,
details: { ...payload.details, selectedStoryCount: this.selectedStoryCountForLastRun },
});
const status = 'status' in payload ? payload.status : undefined;
const progress = 'progress' in payload ? payload.progress : undefined;
if (
((status === 'success' || status === 'cancelled') && progress?.finishedAt) ||
status === 'failed'
) {
// reset the count when a test run is fully finished
this.selectedStoryCountForLastRun = 0;
}
}
async reportFatalError(message: string, error: Error | any) {

View File

@ -405,9 +405,9 @@ export default async function postInstall(options: PostinstallOptions) {
);
}
// If there's an existing workspace file, we update that file to include the Storybook test plugin.
// We assume the existing workspaces include the Vite(st) config, so we won't add it.
if (vitestWorkspaceFile) {
// If there's an existing workspace file, we update that file to include the Storybook test plugin.
// We assume the existing workspaces include the Vite(st) config, so we won't add it.
const workspaceTemplate = await loadTemplate('vitest.workspace.template.ts', {
EXTENDS_WORKSPACE: viteConfigFile
? relative(dirname(vitestWorkspaceFile), viteConfigFile)
@ -445,21 +445,26 @@ export default async function postInstall(options: PostinstallOptions) {
logger.line(1);
return;
}
} else if (rootConfig) {
// If there's an existing Vite/Vitest config, we update it to include the Storybook test plugin.
}
// If there's an existing Vite/Vitest config with workspaces, we update it to include the Storybook test plugin.
else if (rootConfig) {
let target, updated;
// For Vitest 3+, we extend the config file, otherwise we fall back to creating a workspace file.
if (isVitest3OrLater) {
const configFile = await fs.readFile(rootConfig, 'utf8');
const hasWorkspaceConfig = configFile.includes('workspace:');
// For Vitest 3+ with an existing workspace option in the config file, we extend the workspace array,
// otherwise we fall back to creating a workspace file.
if (isVitest3OrLater && hasWorkspaceConfig) {
const configTemplate = await loadTemplate('vitest.config.template.ts', {
CONFIG_DIR: options.configDir,
BROWSER_CONFIG: browserConfig,
SETUP_FILE: relative(dirname(rootConfig), vitestSetupFile),
});
const configFile = await fs.readFile(rootConfig, 'utf8');
const source = babelParse(configTemplate);
target = babelParse(configFile);
updated = updateConfigFile(source, target);
}
if (target && updated) {
logger.line(1);
logger.plain(`${step} Updating your ${vitestConfigFile ? 'Vitest' : 'Vite'} config file:`);
@ -502,8 +507,9 @@ export default async function postInstall(options: PostinstallOptions) {
const formattedContent = await formatFileContent(newWorkspaceFile, workspaceTemplate);
await writeFile(newWorkspaceFile, formattedContent);
}
} else {
// If there's no existing Vitest/Vite config, we create a new Vitest config file.
}
// If there's no existing Vitest/Vite config, we create a new Vitest config file.
else {
const newConfigFile = resolve(`vitest.config.${fileExtension}`);
const configTemplate = await loadTemplate('vitest.config.template.ts', {
CONFIG_DIR: options.configDir,

View File

@ -146,6 +146,7 @@ export const experimental_serverChannel = async (channel: Channel, options: Opti
numTotalTests: progress?.numTotalTests,
numFailedTests: progress?.numFailedTests,
numPassedTests: progress?.numPassedTests,
numSelectedStories: payload.details?.selectedStoryCount ?? 0,
});
}
@ -157,6 +158,7 @@ export const experimental_serverChannel = async (channel: Channel, options: Opti
...(options.enableCrashReports && {
error: error && sanitizeError(error),
}),
numSelectedStories: payload.details?.selectedStoryCount ?? 0,
});
}
}

View File

@ -35,4 +35,11 @@ export const modifyErrorMessage = ({ task }: { task: Task }) => {
}
};
// Enable this in 9.0
// beforeAll(() => {
// if (globalThis.globalProjectAnnotations) {
// return globalThis.globalProjectAnnotations.beforeAll();
// }
// });
afterEach(modifyErrorMessage);

View File

@ -5,6 +5,7 @@ import { type RunnerTask, type TaskMeta, type TestContext } from 'vitest';
import {
type Report,
composeConfigs,
composeStory,
getCsfFactoryAnnotations,
} from 'storybook/internal/preview-api';
@ -34,7 +35,7 @@ export const testStory = (
annotations.story,
annotations.meta!,
{ initialGlobals: (await getInitialGlobals?.()) ?? {} },
annotations.preview,
annotations.preview ?? globalThis.globalProjectAnnotations,
exportName
);

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/addon-themes",
"version": "8.6.0-beta.1",
"version": "8.6.0-beta.8",
"description": "Switch between multiple themes for you components in Storybook",
"keywords": [
"css",

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/addon-toolbars",
"version": "8.6.0-beta.1",
"version": "8.6.0-beta.8",
"description": "Create your own toolbar items that control story rendering",
"keywords": [
"addon",

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/addon-viewport",
"version": "8.6.0-beta.1",
"version": "8.6.0-beta.8",
"description": "Build responsive components by adjusting Storybooks viewport size and orientation",
"keywords": [
"addon",

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/builder-vite",
"version": "8.6.0-beta.1",
"version": "8.6.0-beta.8",
"description": "A plugin to run and build Storybooks with Vite",
"homepage": "https://github.com/storybookjs/storybook/tree/next/code/builders/builder-vite/#readme",
"bugs": {

View File

@ -1,6 +1,6 @@
import type { Options } from 'storybook/internal/types';
import { genDynamicImport, genImport, genObjectFromRawEntries } from 'knitwork';
import { genDynamicImport, genObjectFromRawEntries } from 'knitwork';
import { normalize, relative } from 'pathe';
import { dedent } from 'ts-dedent';

View File

@ -1,8 +1,10 @@
import { getFrameworkName, loadPreviewOrConfigFile } from 'storybook/internal/common';
import type { Options, PreviewAnnotation } from 'storybook/internal/types';
import { dedent } from 'ts-dedent';
import { processPreviewAnnotation } from './utils/process-preview-annotation';
import { SB_VIRTUAL_FILES, getResolvedVirtualModuleId } from './virtual-file-names';
import { SB_VIRTUAL_FILES } from './virtual-file-names';
export async function generateModernIframeScriptCode(options: Options, projectRoot: string) {
const { presets, configDir } = options;
@ -21,7 +23,7 @@ export async function generateModernIframeScriptCode(options: Options, projectRo
// This is pulled out to a variable because it is reused in both the initial page load
// and the HMR handler. We don't use the hot.accept callback params because only the changed
// modules are provided, the rest are null. We can just re-import everything again in that case.
const getPreviewAnnotationsFunction = `
const getPreviewAnnotationsFunction = dedent`
const getProjectAnnotations = async (hmrPreviewAnnotationModules = []) => {
const preview = await import('${previewFileUrl}');
@ -43,25 +45,25 @@ export async function generateModernIframeScriptCode(options: Options, projectRo
const generateHMRHandler = (frameworkName: string): string => {
// Web components are not compatible with HMR, so disable HMR, reload page instead.
if (frameworkName === '@storybook/web-components-vite') {
return `
return dedent`
if (import.meta.hot) {
import.meta.hot.decline();
}`.trim();
}
return `
return dedent`
if (import.meta.hot) {
import.meta.hot.accept('${SB_VIRTUAL_FILES.VIRTUAL_STORIES_FILE}', (newModule) => {
// importFn has changed so we need to patch the new one in
window.__STORYBOOK_PREVIEW__.onStoriesChanged({ importFn: newModule.importFn });
// importFn has changed so we need to patch the new one in
window.__STORYBOOK_PREVIEW__.onStoriesChanged({ importFn: newModule.importFn });
});
import.meta.hot.accept(${JSON.stringify(previewAnnotationURLs)}, (previewAnnotationModules) => {
${getPreviewAnnotationsFunction}
// getProjectAnnotations has changed so we need to patch the new one in
window.__STORYBOOK_PREVIEW__.onGetProjectAnnotationsChanged({ getProjectAnnotations: () => getProjectAnnotations(previewAnnotationModules) });
});
}`.trim();
import.meta.hot.accept(${JSON.stringify(previewAnnotationURLs)}, (previewAnnotationModules) => {
${getPreviewAnnotationsFunction}
// getProjectAnnotations has changed so we need to patch the new one in
window.__STORYBOOK_PREVIEW__.onGetProjectAnnotationsChanged({ getProjectAnnotations: () => getProjectAnnotations(previewAnnotationModules) });
});
}`.trim();
};
/**
@ -72,24 +74,22 @@ export async function generateModernIframeScriptCode(options: Options, projectRo
*
* @todo Inline variable and remove `noinspection`
*/
const code = `
const code = dedent`
import { setup } from 'storybook/internal/preview/runtime';
import '${SB_VIRTUAL_FILES.VIRTUAL_ADDON_SETUP_FILE}';
setup();
import { composeConfigs, PreviewWeb, ClientApi } from 'storybook/internal/preview-api';
import { composeConfigs, PreviewWeb } from 'storybook/internal/preview-api';
import { isPreview } from 'storybook/internal/csf';
import { importFn } from '${SB_VIRTUAL_FILES.VIRTUAL_STORIES_FILE}';
${getPreviewAnnotationsFunction}
${getPreviewAnnotationsFunction}
window.__STORYBOOK_PREVIEW__ = window.__STORYBOOK_PREVIEW__ || new PreviewWeb(importFn, getProjectAnnotations);
window.__STORYBOOK_PREVIEW__ = window.__STORYBOOK_PREVIEW__ || new PreviewWeb(importFn, getProjectAnnotations);
window.__STORYBOOK_STORY_STORE__ = window.__STORYBOOK_STORY_STORE__ || window.__STORYBOOK_PREVIEW__.storyStore;
window.__STORYBOOK_STORY_STORE__ = window.__STORYBOOK_STORY_STORE__ || window.__STORYBOOK_PREVIEW__.storyStore;
${generateHMRHandler(frameworkName)};
`.trim();
${generateHMRHandler(frameworkName)};`.trim();
return code;
}

View File

@ -7,7 +7,6 @@ import type { Middleware, Options } from 'storybook/internal/types';
import type { ViteDevServer } from 'vite';
import { build as viteBuild } from './build';
import { transformIframeHtml } from './transform-iframe-html';
import type { ViteBuilder } from './types';
import { createViteServer } from './vite-server';
@ -16,22 +15,8 @@ export { hasVitePlugins } from './utils/has-vite-plugins';
export * from './types';
function iframeMiddleware(options: Options, server: ViteDevServer): Middleware {
return async (req, res, next) => {
if (!req.url || !req.url.match(/^\/iframe\.html($|\?)/)) {
next();
return;
}
// the base isn't used for anything, but it's required by the URL constructor
const url = new URL(req.url, 'http://localhost:6006');
// We need to handle `html-proxy` params for style tag HMR https://github.com/storybookjs/builder-vite/issues/266#issuecomment-1055677865
// e.g. /iframe.html?html-proxy&index=0.css
if (url.searchParams.has('html-proxy')) {
next();
return;
}
function iframeHandler(options: Options, server: ViteDevServer): Middleware {
return async (req, res) => {
const indexHtml = await readFile(require.resolve('@storybook/builder-vite/input/iframe.html'), {
encoding: 'utf8',
});
@ -57,7 +42,7 @@ export const start: ViteBuilder['start'] = async ({
}) => {
server = await createViteServer(options as Options, devServer);
router.use(iframeMiddleware(options as Options, server));
router.get('/iframe.html', iframeHandler(options as Options, server));
router.use(server.middlewares);
return {

View File

@ -17,7 +17,6 @@ const INCLUDE_CANDIDATES = [
'@storybook/addon-backgrounds/preview',
'@storybook/addon-designs/blocks',
'@storybook/addon-docs/preview',
'@storybook/addon-essentials/preview',
'@storybook/addon-essentials/actions/preview',
'@storybook/addon-essentials/actions/preview',
'@storybook/addon-essentials/backgrounds/preview',
@ -27,6 +26,7 @@ const INCLUDE_CANDIDATES = [
'@storybook/addon-essentials/outline/preview',
'@storybook/addon-essentials/viewport/preview',
'@storybook/addon-highlight/preview',
'@storybook/addon-interactions/preview',
'@storybook/addon-links/preview',
'@storybook/addon-measure/preview',
'@storybook/addon-outline/preview',
@ -132,6 +132,7 @@ const INCLUDE_CANDIDATES = [
'react-textarea-autosize',
'react',
'react/jsx-runtime',
'react/jsx-dev-runtime',
'refractor/core',
'refractor/lang/bash.js',
'refractor/lang/css.js',
@ -150,6 +151,7 @@ const INCLUDE_CANDIDATES = [
'slash',
'store2',
'storybook/internal/preview/runtime',
'storybook/internal/csf',
'synchronous-promise',
'telejson',
'ts-dedent',

View File

@ -9,17 +9,17 @@ import type { Plugin } from 'vite';
export async function stripStoryHMRBoundary(): Promise<Plugin> {
const { createFilter } = await import('vite');
const filter = createFilter(/\.stories\.([tj])sx?$/);
const filter = createFilter(/\.stories\.\w+$/);
return {
name: 'storybook:strip-hmr-boundary-plugin',
enforce: 'post',
async transform(src: string, id: string) {
async transform(src, id) {
if (!filter(id)) {
return undefined;
}
const s = new MagicString(src);
s.replace(/import\.meta\.hot\.accept\(\);/, '');
s.replace(/import\.meta\.hot\.accept\w*/, '(function hmrBoundaryNoop(){})');
return {
code: s.toString(),

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/builder-webpack5",
"version": "8.6.0-beta.1",
"version": "8.6.0-beta.8",
"description": "Storybook framework-agnostic API",
"keywords": [
"storybook"

View File

@ -16,7 +16,7 @@ import prettyTime from 'pretty-hrtime';
import sirv from 'sirv';
import { corePath } from 'storybook/core-path';
import type { Configuration, Stats, StatsOptions } from 'webpack';
import webpackDep, { DefinePlugin, ProgressPlugin } from 'webpack';
import webpackDep, { DefinePlugin, IgnorePlugin, ProgressPlugin } from 'webpack';
import webpackDevMiddleware from 'webpack-dev-middleware';
import webpackHotMiddleware from 'webpack-hot-middleware';
@ -24,6 +24,7 @@ export * from './types';
export * from './preview/virtual-module-mapping';
export const WebpackDefinePlugin = DefinePlugin;
export const WebpackIgnorePlugin = IgnorePlugin;
export const printDuration = (startTime: [number, number]) =>
prettyTime(process.hrtime(startTime))

View File

@ -83,9 +83,5 @@
import './sb-manager/runtime.js';
</script>
<% if (!ignorePreview) { %>
<link href="./sb-preview/runtime.js" rel="prefetch" as="script" />
<% } %>
</body>
</html>

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/core",
"version": "8.6.0-beta.1",
"version": "8.6.0-beta.8",
"description": "Storybook framework-agnostic API",
"keywords": [
"storybook"
@ -361,7 +361,7 @@
"downshift": "^9.0.4",
"ejs": "^3.1.10",
"es-toolkit": "^1.22.0",
"esbuild": "^0.25.0",
"esbuild": "^0.18.0 || ^0.19.0 || ^0.20.0 || ^0.21.0 || ^0.22.0 || ^0.23.0 || ^0.24.0 || ^0.25.0",
"esbuild-plugin-alias": "^0.2.1",
"execa": "^8.0.1",
"fd-package-json": "^1.2.0",

View File

@ -34,7 +34,7 @@ export async function getAddonAnnotations(addon: string) {
// for backwards compatibility, if it's not a core addon we use /preview entrypoint
if (!data.isCoreAddon) {
data.importPath = `@storybook/${addon}/preview`;
data.importPath = `${addon}/preview`;
}
require.resolve(path.join(addon, 'preview'));

View File

@ -13,7 +13,7 @@ import findCacheDirectory from 'find-cache-dir';
*/
export function resolvePathInStorybookCache(fileOrDirectoryName: string, sub = 'default'): string {
let cacheDirectory = findCacheDirectory({ name: 'storybook' });
cacheDirectory ||= join(process.cwd(), '.cache', 'storybook');
cacheDirectory ||= join(process.cwd(), 'node_modules', '.cache', 'storybook');
return join(cacheDirectory, sub, fileOrDirectoryName);
}

View File

@ -1,88 +1,88 @@
// auto generated file, do not edit
export default {
'@storybook/addon-a11y': '8.6.0-beta.1',
'@storybook/addon-actions': '8.6.0-beta.1',
'@storybook/addon-backgrounds': '8.6.0-beta.1',
'@storybook/addon-controls': '8.6.0-beta.1',
'@storybook/addon-docs': '8.6.0-beta.1',
'@storybook/addon-essentials': '8.6.0-beta.1',
'@storybook/addon-mdx-gfm': '8.6.0-beta.1',
'@storybook/addon-highlight': '8.6.0-beta.1',
'@storybook/addon-interactions': '8.6.0-beta.1',
'@storybook/addon-jest': '8.6.0-beta.1',
'@storybook/addon-links': '8.6.0-beta.1',
'@storybook/addon-measure': '8.6.0-beta.1',
'@storybook/addon-onboarding': '8.6.0-beta.1',
'@storybook/addon-outline': '8.6.0-beta.1',
'@storybook/addon-storysource': '8.6.0-beta.1',
'@storybook/experimental-addon-test': '8.6.0-beta.1',
'@storybook/addon-themes': '8.6.0-beta.1',
'@storybook/addon-toolbars': '8.6.0-beta.1',
'@storybook/addon-viewport': '8.6.0-beta.1',
'@storybook/builder-vite': '8.6.0-beta.1',
'@storybook/builder-webpack5': '8.6.0-beta.1',
'@storybook/core': '8.6.0-beta.1',
'@storybook/builder-manager': '8.6.0-beta.1',
'@storybook/channels': '8.6.0-beta.1',
'@storybook/client-logger': '8.6.0-beta.1',
'@storybook/components': '8.6.0-beta.1',
'@storybook/core-common': '8.6.0-beta.1',
'@storybook/core-events': '8.6.0-beta.1',
'@storybook/core-server': '8.6.0-beta.1',
'@storybook/csf-tools': '8.6.0-beta.1',
'@storybook/docs-tools': '8.6.0-beta.1',
'@storybook/manager': '8.6.0-beta.1',
'@storybook/manager-api': '8.6.0-beta.1',
'@storybook/node-logger': '8.6.0-beta.1',
'@storybook/preview': '8.6.0-beta.1',
'@storybook/preview-api': '8.6.0-beta.1',
'@storybook/router': '8.6.0-beta.1',
'@storybook/telemetry': '8.6.0-beta.1',
'@storybook/theming': '8.6.0-beta.1',
'@storybook/types': '8.6.0-beta.1',
'@storybook/angular': '8.6.0-beta.1',
'@storybook/ember': '8.6.0-beta.1',
'@storybook/experimental-nextjs-vite': '8.6.0-beta.1',
'@storybook/html-vite': '8.6.0-beta.1',
'@storybook/html-webpack5': '8.6.0-beta.1',
'@storybook/nextjs': '8.6.0-beta.1',
'@storybook/preact-vite': '8.6.0-beta.1',
'@storybook/preact-webpack5': '8.6.0-beta.1',
'@storybook/react-native-web-vite': '8.6.0-beta.1',
'@storybook/react-vite': '8.6.0-beta.1',
'@storybook/react-webpack5': '8.6.0-beta.1',
'@storybook/server-webpack5': '8.6.0-beta.1',
'@storybook/svelte-vite': '8.6.0-beta.1',
'@storybook/svelte-webpack5': '8.6.0-beta.1',
'@storybook/sveltekit': '8.6.0-beta.1',
'@storybook/vue3-vite': '8.6.0-beta.1',
'@storybook/vue3-webpack5': '8.6.0-beta.1',
'@storybook/web-components-vite': '8.6.0-beta.1',
'@storybook/web-components-webpack5': '8.6.0-beta.1',
'@storybook/blocks': '8.6.0-beta.1',
storybook: '8.6.0-beta.1',
sb: '8.6.0-beta.1',
'@storybook/cli': '8.6.0-beta.1',
'@storybook/codemod': '8.6.0-beta.1',
'@storybook/core-webpack': '8.6.0-beta.1',
'create-storybook': '8.6.0-beta.1',
'@storybook/csf-plugin': '8.6.0-beta.1',
'@storybook/instrumenter': '8.6.0-beta.1',
'@storybook/react-dom-shim': '8.6.0-beta.1',
'@storybook/source-loader': '8.6.0-beta.1',
'@storybook/test': '8.6.0-beta.1',
'@storybook/preset-create-react-app': '8.6.0-beta.1',
'@storybook/preset-html-webpack': '8.6.0-beta.1',
'@storybook/preset-preact-webpack': '8.6.0-beta.1',
'@storybook/preset-react-webpack': '8.6.0-beta.1',
'@storybook/preset-server-webpack': '8.6.0-beta.1',
'@storybook/preset-svelte-webpack': '8.6.0-beta.1',
'@storybook/preset-vue3-webpack': '8.6.0-beta.1',
'@storybook/html': '8.6.0-beta.1',
'@storybook/preact': '8.6.0-beta.1',
'@storybook/react': '8.6.0-beta.1',
'@storybook/server': '8.6.0-beta.1',
'@storybook/svelte': '8.6.0-beta.1',
'@storybook/vue3': '8.6.0-beta.1',
'@storybook/web-components': '8.6.0-beta.1',
'@storybook/addon-a11y': '8.6.0-beta.8',
'@storybook/addon-actions': '8.6.0-beta.8',
'@storybook/addon-backgrounds': '8.6.0-beta.8',
'@storybook/addon-controls': '8.6.0-beta.8',
'@storybook/addon-docs': '8.6.0-beta.8',
'@storybook/addon-essentials': '8.6.0-beta.8',
'@storybook/addon-mdx-gfm': '8.6.0-beta.8',
'@storybook/addon-highlight': '8.6.0-beta.8',
'@storybook/addon-interactions': '8.6.0-beta.8',
'@storybook/addon-jest': '8.6.0-beta.8',
'@storybook/addon-links': '8.6.0-beta.8',
'@storybook/addon-measure': '8.6.0-beta.8',
'@storybook/addon-onboarding': '8.6.0-beta.8',
'@storybook/addon-outline': '8.6.0-beta.8',
'@storybook/addon-storysource': '8.6.0-beta.8',
'@storybook/experimental-addon-test': '8.6.0-beta.8',
'@storybook/addon-themes': '8.6.0-beta.8',
'@storybook/addon-toolbars': '8.6.0-beta.8',
'@storybook/addon-viewport': '8.6.0-beta.8',
'@storybook/builder-vite': '8.6.0-beta.8',
'@storybook/builder-webpack5': '8.6.0-beta.8',
'@storybook/core': '8.6.0-beta.8',
'@storybook/builder-manager': '8.6.0-beta.8',
'@storybook/channels': '8.6.0-beta.8',
'@storybook/client-logger': '8.6.0-beta.8',
'@storybook/components': '8.6.0-beta.8',
'@storybook/core-common': '8.6.0-beta.8',
'@storybook/core-events': '8.6.0-beta.8',
'@storybook/core-server': '8.6.0-beta.8',
'@storybook/csf-tools': '8.6.0-beta.8',
'@storybook/docs-tools': '8.6.0-beta.8',
'@storybook/manager': '8.6.0-beta.8',
'@storybook/manager-api': '8.6.0-beta.8',
'@storybook/node-logger': '8.6.0-beta.8',
'@storybook/preview': '8.6.0-beta.8',
'@storybook/preview-api': '8.6.0-beta.8',
'@storybook/router': '8.6.0-beta.8',
'@storybook/telemetry': '8.6.0-beta.8',
'@storybook/theming': '8.6.0-beta.8',
'@storybook/types': '8.6.0-beta.8',
'@storybook/angular': '8.6.0-beta.8',
'@storybook/ember': '8.6.0-beta.8',
'@storybook/experimental-nextjs-vite': '8.6.0-beta.8',
'@storybook/html-vite': '8.6.0-beta.8',
'@storybook/html-webpack5': '8.6.0-beta.8',
'@storybook/nextjs': '8.6.0-beta.8',
'@storybook/preact-vite': '8.6.0-beta.8',
'@storybook/preact-webpack5': '8.6.0-beta.8',
'@storybook/react-native-web-vite': '8.6.0-beta.8',
'@storybook/react-vite': '8.6.0-beta.8',
'@storybook/react-webpack5': '8.6.0-beta.8',
'@storybook/server-webpack5': '8.6.0-beta.8',
'@storybook/svelte-vite': '8.6.0-beta.8',
'@storybook/svelte-webpack5': '8.6.0-beta.8',
'@storybook/sveltekit': '8.6.0-beta.8',
'@storybook/vue3-vite': '8.6.0-beta.8',
'@storybook/vue3-webpack5': '8.6.0-beta.8',
'@storybook/web-components-vite': '8.6.0-beta.8',
'@storybook/web-components-webpack5': '8.6.0-beta.8',
'@storybook/blocks': '8.6.0-beta.8',
storybook: '8.6.0-beta.8',
sb: '8.6.0-beta.8',
'@storybook/cli': '8.6.0-beta.8',
'@storybook/codemod': '8.6.0-beta.8',
'@storybook/core-webpack': '8.6.0-beta.8',
'create-storybook': '8.6.0-beta.8',
'@storybook/csf-plugin': '8.6.0-beta.8',
'@storybook/instrumenter': '8.6.0-beta.8',
'@storybook/react-dom-shim': '8.6.0-beta.8',
'@storybook/source-loader': '8.6.0-beta.8',
'@storybook/test': '8.6.0-beta.8',
'@storybook/preset-create-react-app': '8.6.0-beta.8',
'@storybook/preset-html-webpack': '8.6.0-beta.8',
'@storybook/preset-preact-webpack': '8.6.0-beta.8',
'@storybook/preset-react-webpack': '8.6.0-beta.8',
'@storybook/preset-server-webpack': '8.6.0-beta.8',
'@storybook/preset-svelte-webpack': '8.6.0-beta.8',
'@storybook/preset-vue3-webpack': '8.6.0-beta.8',
'@storybook/html': '8.6.0-beta.8',
'@storybook/preact': '8.6.0-beta.8',
'@storybook/react': '8.6.0-beta.8',
'@storybook/server': '8.6.0-beta.8',
'@storybook/svelte': '8.6.0-beta.8',
'@storybook/vue3': '8.6.0-beta.8',
'@storybook/web-components': '8.6.0-beta.8',
};

View File

@ -78,13 +78,14 @@ export async function storybookDevServer(options: Options) {
channel: serverChannel,
});
let previewStarted: Promise<any> = Promise.resolve();
let previewResult: Awaited<ReturnType<(typeof previewBuilder)['start']>> =
await Promise.resolve();
if (!options.ignorePreview) {
if (!options.quiet) {
logger.info('=> Starting preview..');
}
previewStarted = previewBuilder
previewResult = await previewBuilder
.start({
startTime: process.hrtime(),
options,
@ -108,14 +109,6 @@ export async function storybookDevServer(options: Options) {
});
}
// this is a preview route, the builder has to be started before we can serve it
// this handler keeps request to that route pending until the builder is ready to serve it, preventing a 404
app.use('/iframe.html', (req, res, next) => {
// We need to catch here or node will treat any errors thrown by `previewStarted` as
// unhandled and exit (even though they are very much handled below)
previewStarted.catch(() => {}).then(() => next());
});
const listening = new Promise<void>((resolve, reject) => {
server.once('error', reject);
app.listen({ port, host }, resolve);
@ -132,8 +125,6 @@ export async function storybookDevServer(options: Options) {
throw indexError;
}
const previewResult = await previewStarted;
// Now the preview has successfully started, we can count this as a 'dev' event.
doTelemetry(app, core, initializedStoryIndexGenerator, options);

View File

@ -21,19 +21,26 @@ export interface Preview<TRenderer extends Renderer = Renderer> {
}
export function definePreview<TRenderer extends Renderer>(
preview: Preview<TRenderer>['input']
input: Preview<TRenderer>['input']
): Preview<TRenderer> {
return {
let composed: NormalizedProjectAnnotations<TRenderer>;
const preview: Preview<TRenderer> = {
_tag: 'Preview',
input: preview,
input,
get composed() {
const { addons, ...rest } = preview;
return normalizeProjectAnnotations<TRenderer>(composeConfigs([...(addons ?? []), rest]));
if (composed) {
return composed;
}
const { addons, ...rest } = input;
composed = normalizeProjectAnnotations<TRenderer>(composeConfigs([...(addons ?? []), rest]));
return composed;
},
meta(meta: ComponentAnnotations<TRenderer>) {
return defineMeta(meta, this);
},
};
globalThis.globalProjectAnnotations = preview.composed;
return preview;
}
export function isPreview(input: unknown): input is Preview<Renderer> {
@ -46,7 +53,7 @@ export interface Meta<TRenderer extends Renderer, TArgs extends Args = Args> {
composed: NormalizedComponentAnnotations<TRenderer>;
preview: Preview<TRenderer>;
story(input: ComponentAnnotations<TRenderer, TArgs>): Story<TRenderer, TArgs>;
story(input: StoryAnnotations<TRenderer, TArgs>): Story<TRenderer, TArgs>;
}
export function isMeta(input: unknown): input is Meta<Renderer> {

View File

@ -1 +1 @@
export const version = '8.6.0-beta.1';
export const version = '8.6.0-beta.8';

View File

@ -1,58 +1,70 @@
import type { FC } from 'react';
import React from 'react';
import React, { useMemo, useState } from 'react';
import { type API_LeafEntry, Addon_TypesEnum } from '@storybook/core/types';
import { Addon_TypesEnum } from '@storybook/core/types';
import { Consumer } from '@storybook/core/manager-api';
import type { API, Combo } from '@storybook/core/manager-api';
import memoize from 'memoizerific';
import { useChannel, useStorybookApi, useStorybookState } from '@storybook/core/manager-api';
import { STORY_PREPARED } from '../../core-events';
import { AddonPanel } from '../components/panel/Panel';
const createPanelActions = memoize(1)((api) => ({
onSelect: (panel: string) => api.setSelectedPanel(panel),
toggleVisibility: () => api.togglePanel(),
togglePosition: () => api.togglePanelPosition(),
}));
const Panel: FC<any> = (props) => {
const api = useStorybookApi();
const state = useStorybookState();
const [story, setStory] = useState(api.getCurrentStoryData());
const getPanels = memoize(1)((api: API, story: API_LeafEntry) => {
const allPanels = api.getElements(Addon_TypesEnum.PANEL);
useChannel(
{
[STORY_PREPARED]: () => {
setStory(api.getCurrentStoryData());
},
},
[]
);
if (!allPanels || !story || story.type !== 'story') {
return allPanels;
}
const { parameters, type } = story ?? {};
const { parameters } = story;
const panelActions = useMemo(
() => ({
onSelect: (panel: string) => api.setSelectedPanel(panel),
toggleVisibility: () => api.togglePanel(),
togglePosition: () => api.togglePanelPosition(),
}),
[api]
);
const filteredPanels: typeof allPanels = {};
Object.entries(allPanels).forEach(([id, panel]) => {
const { paramKey }: any = panel;
if (paramKey && parameters && parameters[paramKey] && parameters[paramKey].disable) {
return;
const panels = useMemo(() => {
const allPanels = api.getElements(Addon_TypesEnum.PANEL);
if (!allPanels || type !== 'story') {
return allPanels;
}
if (
panel.disabled === true ||
(typeof panel.disabled === 'function' && panel.disabled(parameters))
) {
return;
}
filteredPanels[id] = panel;
});
return filteredPanels;
});
const filteredPanels: typeof allPanels = {};
Object.entries(allPanels).forEach(([id, p]) => {
const { paramKey }: any = p;
if (paramKey && parameters && parameters[paramKey] && parameters[paramKey].disable) {
return;
}
if (p.disabled === true || (typeof p.disabled === 'function' && p.disabled(parameters))) {
return;
}
filteredPanels[id] = p;
});
const mapper = ({ state, api }: Combo) => ({
panels: getPanels(api, api.getCurrentStoryData()),
selectedPanel: api.getSelectedPanel(),
panelPosition: state.layout.panelPosition,
actions: createPanelActions(api),
shortcuts: api.getShortcutKeys(),
});
return filteredPanels;
}, [api, type, parameters]);
const Panel: FC<any> = (props) => (
<Consumer filter={mapper}>{(customProps) => <AddonPanel {...props} {...customProps} />}</Consumer>
);
return (
<AddonPanel
panels={panels}
selectedPanel={api.getSelectedPanel()}
panelPosition={state.layout.panelPosition}
actions={panelActions}
shortcuts={api.getShortcutKeys()}
{...props}
/>
);
};
export default Panel;

View File

@ -1,7 +1,7 @@
/* eslint-disable no-underscore-dangle */
/* eslint-disable @typescript-eslint/naming-convention */
import { type CleanupCallback, isExportStory } from '@storybook/core/csf';
import { type CleanupCallback, type Preview, isExportStory } from '@storybook/core/csf';
import type {
Args,
Canvas,
@ -73,7 +73,10 @@ export function setProjectAnnotations<TRenderer extends Renderer = Renderer>(
| NamedOrDefaultProjectAnnotations<TRenderer>[]
): NormalizedProjectAnnotations<TRenderer> {
const annotations = Array.isArray(projectAnnotations) ? projectAnnotations : [projectAnnotations];
globalThis.globalProjectAnnotations = composeConfigs(annotations.map(extractAnnotation));
globalThis.globalProjectAnnotations = composeConfigs([
globalThis.defaultProjectAnnotations ?? {},
composeConfigs(annotations.map(extractAnnotation)),
]);
/*
We must return the composition of default and global annotations here
@ -82,10 +85,7 @@ export function setProjectAnnotations<TRenderer extends Renderer = Renderer>(
const projectAnnotations = setProjectAnnotations(...);
beforeAll(projectAnnotations.beforeAll)
*/
return composeConfigs([
globalThis.defaultProjectAnnotations ?? {},
globalThis.globalProjectAnnotations ?? {},
]);
return globalThis.globalProjectAnnotations ?? {};
}
const cleanups: CleanupCallback[] = [];
@ -123,10 +123,7 @@ export function composeStory<TRenderer extends Renderer = Renderer, TArgs extend
const normalizedProjectAnnotations = normalizeProjectAnnotations<TRenderer>(
composeConfigs([
defaultConfig && Object.keys(defaultConfig).length > 0
? defaultConfig
: (globalThis.defaultProjectAnnotations ?? {}),
globalThis.globalProjectAnnotations ?? {},
defaultConfig ?? globalThis.globalProjectAnnotations ?? {},
projectAnnotations ?? {},
])
);
@ -165,6 +162,8 @@ export function composeStory<TRenderer extends Renderer = Renderer, TArgs extend
mount: null!,
});
context.parameters.__isPortableStory = true;
context.context = context;
if (story.renderToCanvas) {

View File

@ -1,7 +1,12 @@
import type { ViewMode as ViewModeBase } from '@storybook/core/csf';
import type { Renderer as CSFRenderer } from '@storybook/core/csf';
import type { Addon_OptionsParameter } from './addons';
// Fix https://github.com/storybookjs/storybook/issues/30540
// Can be removed once @storybook/core and storybook are merged in 9.0
export interface Renderer extends CSFRenderer {}
export type {
AfterEach,
AnnotatedStoryFn,
@ -35,7 +40,6 @@ export type {
PlayFunction,
PlayFunctionContext,
ProjectAnnotations as BaseProjectAnnotations,
Renderer,
SBArrayType,
SBEnumType,
SBIntersectionType,

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/builder-manager",
"version": "8.6.0-beta.1",
"version": "8.6.0-beta.8",
"description": "Storybook manager builder",
"keywords": [
"storybook"

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/channels",
"version": "8.6.0-beta.1",
"version": "8.6.0-beta.8",
"description": "",
"keywords": [
"storybook"

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/client-logger",
"version": "8.6.0-beta.1",
"version": "8.6.0-beta.8",
"description": "",
"keywords": [
"storybook"

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/components",
"version": "8.6.0-beta.1",
"version": "8.6.0-beta.8",
"description": "Core Storybook Components",
"keywords": [
"storybook"

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/core-common",
"version": "8.6.0-beta.1",
"version": "8.6.0-beta.8",
"description": "Storybook framework-agnostic API",
"keywords": [
"storybook"

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/core-events",
"version": "8.6.0-beta.1",
"version": "8.6.0-beta.8",
"description": "Event names used in storybook core",
"keywords": [
"storybook"

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/core-server",
"version": "8.6.0-beta.1",
"version": "8.6.0-beta.8",
"description": "Storybook framework-agnostic API",
"keywords": [
"storybook"

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/csf-tools",
"version": "8.6.0-beta.1",
"version": "8.6.0-beta.8",
"description": "Parse and manipulate CSF and Storybook config files",
"keywords": [
"storybook"

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/docs-tools",
"version": "8.6.0-beta.1",
"version": "8.6.0-beta.8",
"description": "Shared utility functions for frameworks to implement docs",
"keywords": [
"storybook"

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/manager-api",
"version": "8.6.0-beta.1",
"version": "8.6.0-beta.8",
"description": "Core Storybook Manager API & Context",
"keywords": [
"storybook"

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/manager",
"version": "8.6.0-beta.1",
"version": "8.6.0-beta.8",
"description": "Core Storybook UI",
"keywords": [
"storybook"

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/node-logger",
"version": "8.6.0-beta.1",
"version": "8.6.0-beta.8",
"description": "",
"keywords": [
"storybook"

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/preview-api",
"version": "8.6.0-beta.1",
"version": "8.6.0-beta.8",
"description": "",
"keywords": [
"storybook"

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/preview",
"version": "8.6.0-beta.1",
"version": "8.6.0-beta.8",
"description": "",
"keywords": [
"storybook"

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/router",
"version": "8.6.0-beta.1",
"version": "8.6.0-beta.8",
"description": "Core Storybook Router",
"keywords": [
"storybook"

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/telemetry",
"version": "8.6.0-beta.1",
"version": "8.6.0-beta.8",
"description": "Telemetry logging for crash reports and usage statistics",
"keywords": [
"storybook"

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/theming",
"version": "8.6.0-beta.1",
"version": "8.6.0-beta.8",
"description": "Core Storybook Components",
"keywords": [
"storybook"

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/types",
"version": "8.6.0-beta.1",
"version": "8.6.0-beta.8",
"description": "Core Storybook TS Types",
"keywords": [
"storybook"

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/angular",
"version": "8.6.0-beta.1",
"version": "8.6.0-beta.8",
"description": "Storybook for Angular: Develop Angular components in isolation with hot reloading.",
"keywords": [
"storybook",
@ -101,6 +101,7 @@
"@angular-devkit/architect": ">=0.1500.0 < 0.2000.0",
"@angular-devkit/build-angular": ">=15.0.0 < 20.0.0",
"@angular-devkit/core": ">=15.0.0 < 20.0.0",
"@angular/animations": ">=15.0.0 < 20.0.0",
"@angular/cli": ">=15.0.0 < 20.0.0",
"@angular/common": ">=15.0.0 < 20.0.0",
"@angular/compiler": ">=15.0.0 < 20.0.0",
@ -115,6 +116,9 @@
"zone.js": ">= 0.11.1 < 1.0.0"
},
"peerDependenciesMeta": {
"@angular/animations": {
"optional": true
},
"@angular/cli": {
"optional": true
},

View File

@ -101,6 +101,7 @@ export abstract class AbstractRenderer {
this.initAngularRootElement(targetDOMNode, targetSelector);
const analyzedMetadata = new PropertyExtractor(storyFnAngular.moduleMetadata, component);
await analyzedMetadata.init();
const storyUid = this.generateStoryUIdFromRawStoryUid(
targetDOMNode.getAttribute(STORY_UID_ATTRIBUTE)

View File

@ -59,6 +59,7 @@ describe('StorybookModule', () => {
};
const analyzedMetadata = new PropertyExtractor({}, FooComponent);
await analyzedMetadata.init();
const application = getApplication({
storyFnAngular: { props },
@ -98,6 +99,7 @@ describe('StorybookModule', () => {
};
const analyzedMetadata = new PropertyExtractor({}, FooComponent);
await analyzedMetadata.init();
const application = getApplication({
storyFnAngular: { props },
@ -127,6 +129,7 @@ describe('StorybookModule', () => {
const storyProps$ = new BehaviorSubject<ICollection>(initialProps);
const analyzedMetadata = new PropertyExtractor({}, FooComponent);
await analyzedMetadata.init();
const application = getApplication({
storyFnAngular: { props: initialProps },
@ -183,6 +186,7 @@ describe('StorybookModule', () => {
const storyProps$ = new BehaviorSubject<ICollection>(initialProps);
const analyzedMetadata = new PropertyExtractor({}, FooComponent);
await analyzedMetadata.init();
const application = getApplication({
storyFnAngular: { props: initialProps },
@ -224,6 +228,7 @@ describe('StorybookModule', () => {
const storyProps$ = new BehaviorSubject<ICollection>(initialProps);
const analyzedMetadata = new PropertyExtractor({}, FooComponent);
await analyzedMetadata.init();
const application = getApplication({
storyFnAngular: {
@ -262,6 +267,7 @@ describe('StorybookModule', () => {
const storyProps$ = new BehaviorSubject<ICollection>(initialProps);
const analyzedMetadata = new PropertyExtractor({}, FooComponent);
await analyzedMetadata.init();
const application = getApplication({
storyFnAngular: { props: initialProps },
@ -302,6 +308,8 @@ describe('StorybookModule', () => {
WithoutSelectorComponent
);
await analyzedMetadata.init();
const application = getApplication({
storyFnAngular: {
props,
@ -330,6 +338,7 @@ describe('StorybookModule', () => {
class FooComponent {}
const analyzedMetadata = new PropertyExtractor({}, FooComponent);
await analyzedMetadata.init();
const application = getApplication({
storyFnAngular: { template: '' },

View File

@ -29,75 +29,81 @@ const TestModuleWithImportsAndProviders = NgModule({
providers: [TestTokenProvider],
})(class {});
const analyzeMetadata = (metadata: NgModuleMetadata, component?: any) => {
return new PropertyExtractor(metadata, component);
const analyzeMetadata = async (metadata: NgModuleMetadata, component?: any) => {
const propertyExtractor = new PropertyExtractor(metadata, component);
await propertyExtractor.init();
return propertyExtractor;
};
const extractImports = (metadata: NgModuleMetadata, component?: any) => {
const { imports } = new PropertyExtractor(metadata, component);
return imports;
const extractImports = async (metadata: NgModuleMetadata, component?: any) => {
const propertyExtractor = new PropertyExtractor(metadata, component);
await propertyExtractor.init();
return propertyExtractor.imports;
};
const extractDeclarations = (metadata: NgModuleMetadata, component?: any) => {
const { declarations } = new PropertyExtractor(metadata, component);
return declarations;
const extractDeclarations = async (metadata: NgModuleMetadata, component?: any) => {
const propertyExtractor = new PropertyExtractor(metadata, component);
await propertyExtractor.init();
return propertyExtractor.declarations;
};
const extractProviders = (metadata: NgModuleMetadata, component?: any) => {
const { providers } = new PropertyExtractor(metadata, component);
return providers;
const extractProviders = async (metadata: NgModuleMetadata, component?: any) => {
const propertyExtractor = new PropertyExtractor(metadata, component);
await propertyExtractor.init();
return propertyExtractor.providers;
};
const extractApplicationProviders = (metadata: NgModuleMetadata, component?: any) => {
const { applicationProviders } = new PropertyExtractor(metadata, component);
return applicationProviders;
const extractApplicationProviders = async (metadata: NgModuleMetadata, component?: any) => {
const propertyExtractor = new PropertyExtractor(metadata, component);
await propertyExtractor.init();
return propertyExtractor.applicationProviders;
};
describe('PropertyExtractor', () => {
vi.spyOn(console, 'warn').mockImplementation(() => {});
describe('analyzeMetadata', () => {
it('should remove BrowserModule', () => {
it('should remove BrowserModule', async () => {
const metadata = {
imports: [BrowserModule],
};
const { imports, providers, applicationProviders } = analyzeMetadata(metadata);
const { imports, providers, applicationProviders } = await analyzeMetadata(metadata);
expect(imports.flat(Number.MAX_VALUE)).toEqual([CommonModule]);
expect(providers.flat(Number.MAX_VALUE)).toEqual([]);
expect(applicationProviders.flat(Number.MAX_VALUE)).toEqual([]);
});
it('should remove BrowserAnimationsModule and use its providers instead', () => {
it('should remove BrowserAnimationsModule and use its providers instead', async () => {
const metadata = {
imports: [BrowserAnimationsModule],
};
const { imports, providers, applicationProviders } = analyzeMetadata(metadata);
const { imports, providers, applicationProviders } = await analyzeMetadata(metadata);
expect(imports.flat(Number.MAX_VALUE)).toEqual([CommonModule]);
expect(providers.flat(Number.MAX_VALUE)).toEqual([]);
expect(applicationProviders.flat(Number.MAX_VALUE)).toEqual(provideAnimations());
});
it('should remove NoopAnimationsModule and use its providers instead', () => {
it('should remove NoopAnimationsModule and use its providers instead', async () => {
const metadata = {
imports: [NoopAnimationsModule],
};
const { imports, providers, applicationProviders } = analyzeMetadata(metadata);
const { imports, providers, applicationProviders } = await analyzeMetadata(metadata);
expect(imports.flat(Number.MAX_VALUE)).toEqual([CommonModule]);
expect(providers.flat(Number.MAX_VALUE)).toEqual([]);
expect(applicationProviders.flat(Number.MAX_VALUE)).toEqual(provideNoopAnimations());
});
it('should remove Browser/Animations modules recursively', () => {
it('should remove Browser/Animations modules recursively', async () => {
const metadata = {
imports: [BrowserAnimationsModule, BrowserModule],
};
const { imports, providers, applicationProviders } = analyzeMetadata(metadata);
const { imports, providers, applicationProviders } = await analyzeMetadata(metadata);
expect(imports.flat(Number.MAX_VALUE)).toEqual([CommonModule]);
expect(providers.flat(Number.MAX_VALUE)).toEqual([]);
expect(applicationProviders.flat(Number.MAX_VALUE)).toEqual(provideAnimations());
});
it('should not destructure Angular official module', () => {
it('should not destructure Angular official module', async () => {
const metadata = {
imports: [WithOfficialModule],
};
const { imports, providers, applicationProviders } = analyzeMetadata(metadata);
const { imports, providers, applicationProviders } = await analyzeMetadata(metadata);
expect(imports.flat(Number.MAX_VALUE)).toEqual([CommonModule, WithOfficialModule]);
expect(providers.flat(Number.MAX_VALUE)).toEqual([]);
expect(applicationProviders.flat(Number.MAX_VALUE)).toEqual([]);
@ -105,13 +111,13 @@ describe('PropertyExtractor', () => {
});
describe('extractImports', () => {
it('should return Angular official modules', () => {
const imports = extractImports({ imports: [TestModuleWithImportsAndProviders] });
it('should return Angular official modules', async () => {
const imports = await extractImports({ imports: [TestModuleWithImportsAndProviders] });
expect(imports).toEqual([CommonModule, TestModuleWithImportsAndProviders]);
});
it('should return standalone components', () => {
const imports = extractImports(
it('should return standalone components', async () => {
const imports = await extractImports(
{
imports: [TestModuleWithImportsAndProviders],
},
@ -124,8 +130,8 @@ describe('PropertyExtractor', () => {
]);
});
it('should return standalone directives', () => {
const imports = extractImports(
it('should return standalone directives', async () => {
const imports = await extractImports(
{
imports: [TestModuleWithImportsAndProviders],
},
@ -140,8 +146,11 @@ describe('PropertyExtractor', () => {
});
describe('extractDeclarations', () => {
it('should return an array of declarations that contains `storyComponent`', () => {
const declarations = extractDeclarations({ declarations: [TestComponent1] }, TestComponent2);
it('should return an array of declarations that contains `storyComponent`', async () => {
const declarations = await extractDeclarations(
{ declarations: [TestComponent1] },
TestComponent2
);
expect(declarations).toEqual([TestComponent1, TestComponent2]);
});
});
@ -174,15 +183,15 @@ describe('PropertyExtractor', () => {
});
describe('extractProviders', () => {
it('should return an array of providers', () => {
const providers = extractProviders({
it('should return an array of providers', async () => {
const providers = await extractProviders({
providers: [TestService],
});
expect(providers).toEqual([TestService]);
});
it('should return an array of singletons extracted', () => {
const singeltons = extractApplicationProviders({
it('should return an array of singletons extracted', async () => {
const singeltons = await extractApplicationProviders({
imports: [BrowserAnimationsModule],
});

View File

@ -14,12 +14,6 @@ import {
VERSION,
} from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import {
BrowserAnimationsModule,
NoopAnimationsModule,
provideAnimations,
provideNoopAnimations,
} from '@angular/platform-browser/animations';
import { dedent } from 'ts-dedent';
import { NgModuleMetadata } from '../../types';
@ -45,9 +39,7 @@ export class PropertyExtractor implements NgModuleMetadata {
constructor(
private metadata: NgModuleMetadata,
private component?: any
) {
this.init();
}
) {}
// With the new way of mounting standalone components to the DOM via bootstrapApplication API,
// we should now pass ModuleWithProviders to the providers array of the bootstrapApplication function.
@ -71,8 +63,8 @@ export class PropertyExtractor implements NgModuleMetadata {
}
}
private init() {
const analyzed = this.analyzeMetadata(this.metadata);
public async init() {
const analyzed = await this.analyzeMetadata(this.metadata);
this.imports = uniqueArray([CommonModule, analyzed.imports]);
this.providers = uniqueArray(analyzed.providers);
this.applicationProviders = uniqueArray(analyzed.applicationProviders);
@ -101,28 +93,28 @@ export class PropertyExtractor implements NgModuleMetadata {
* - Extracts providers from ModuleWithProviders
* - Returns a new NgModuleMetadata object
*/
private analyzeMetadata = (metadata: NgModuleMetadata) => {
private analyzeMetadata = async (metadata: NgModuleMetadata) => {
const declarations = [...(metadata?.declarations || [])];
const providers = [...(metadata?.providers || [])];
const applicationProviders: Provider[] = [];
const imports = [...(metadata?.imports || [])].reduce((acc, imported) => {
// remove ngModule and use only its providers if it is restricted
// (e.g. BrowserModule, BrowserAnimationsModule, NoopAnimationsModule, ...etc)
const [isRestricted, restrictedProviders] = PropertyExtractor.analyzeRestricted(imported);
if (isRestricted) {
applicationProviders.unshift(restrictedProviders || []);
return acc;
}
acc.push(imported);
return acc;
}, []);
const imports = await Promise.all(
[...(metadata?.imports || [])].map(async (imported) => {
const [isRestricted, restrictedProviders] =
await PropertyExtractor.analyzeRestricted(imported);
if (isRestricted) {
applicationProviders.unshift(restrictedProviders || []);
return null;
}
return imported;
})
).then((results) => results.filter(Boolean));
return { ...metadata, imports, providers, applicationProviders, declarations };
};
static analyzeRestricted = (ngModule: NgModule): [boolean] | [boolean, Provider] => {
static analyzeRestricted = async (
ngModule: NgModule
): Promise<[boolean] | [boolean, Provider]> => {
if (ngModule === BrowserModule) {
console.warn(
dedent`
@ -136,32 +128,38 @@ export class PropertyExtractor implements NgModuleMetadata {
return [true];
}
if (ngModule === BrowserAnimationsModule) {
console.warn(
dedent`
Storybook Warning:
You have added the "BrowserAnimationsModule" to the list of "imports" in your moduleMetadata definition of your Story.
In Storybook 7.0 we use Angular's new 'bootstrapApplication' API to mount the component to the DOM, which accepts a list of providers to set up application-wide providers.
Use the 'applicationConfig' decorator from '@storybook/angular' and add the "provideAnimations" function to the list of "providers".
If your Angular version does not support "provide-like" functions, use the helper function importProvidersFrom instead to set up animations. For this case, please add "importProvidersFrom(BrowserAnimationsModule)" to the list of providers of your applicationConfig definition.
Please visit https://angular.io/guide/standalone-components#configuring-dependency-injection for more information.
`
);
return [true, provideAnimations()];
}
try {
const animations = await import('@angular/platform-browser/animations');
if (ngModule === NoopAnimationsModule) {
console.warn(
dedent`
Storybook Warning:
You have added the "NoopAnimationsModule" to the list of "imports" in your moduleMetadata definition of your Story.
In Storybook v7.0 we are using Angular's new bootstrapApplication API to mount an Angular application to the DOM, which accepts a list of providers to set up application-wide providers.
Use the 'applicationConfig' decorator from '@storybook/angular' and add the "provideNoopAnimations" function to the list of "providers".
If your Angular version does not support "provide-like" functions, use the helper function importProvidersFrom instead to set up noop animations and to extract all necessary providers from NoopAnimationsModule. For this case, please add "importProvidersFrom(NoopAnimationsModule)" to the list of providers of your applicationConfig definition.
Please visit https://angular.io/guide/standalone-components#configuring-dependency-injection for more information.
`
);
return [true, provideNoopAnimations()];
if (ngModule === animations.BrowserAnimationsModule) {
console.warn(
dedent`
Storybook Warning:
You have added the "BrowserAnimationsModule" to the list of "imports" in your moduleMetadata definition of your Story.
In Storybook 7.0 we use Angular's new 'bootstrapApplication' API to mount the component to the DOM, which accepts a list of providers to set up application-wide providers.
Use the 'applicationConfig' decorator from '@storybook/angular' and add the "provideAnimations" function to the list of "providers".
If your Angular version does not support "provide-like" functions, use the helper function importProvidersFrom instead to set up animations. For this case, please add "importProvidersFrom(BrowserAnimationsModule)" to the list of providers of your applicationConfig definition.
Please visit https://angular.io/guide/standalone-components#configuring-dependency-injection for more information.
`
);
return [true, animations.provideAnimations()];
}
if (ngModule === animations.NoopAnimationsModule) {
console.warn(
dedent`
Storybook Warning:
You have added the "NoopAnimationsModule" to the list of "imports" in your moduleMetadata definition of your Story.
In Storybook v7.0 we are using Angular's new bootstrapApplication API to mount an Angular application to the DOM, which accepts a list of providers to set up application-wide providers.
Use the 'applicationConfig' decorator from '@storybook/angular' and add the "provideNoopAnimations" function to the list of "providers".
If your Angular version does not support "provide-like" functions, use the helper function importProvidersFrom instead to set up noop animations and to extract all necessary providers from NoopAnimationsModule. For this case, please add "importProvidersFrom(NoopAnimationsModule)" to the list of providers of your applicationConfig definition.
Please visit https://angular.io/guide/standalone-components#configuring-dependency-injection for more information.
`
);
return [true, animations.provideNoopAnimations()];
}
} catch (e) {
return [false];
}
return [false];

View File

@ -1,6 +1,6 @@
import { logger } from 'storybook/internal/node-logger';
import { AngularLegacyBuildOptionsError } from 'storybook/internal/server-errors';
import { WebpackDefinePlugin } from '@storybook/builder-webpack5';
import { WebpackDefinePlugin, WebpackIgnorePlugin } from '@storybook/builder-webpack5';
import { BuilderContext, targetFromTargetString } from '@angular-devkit/architect';
import { JsonObject, logging } from '@angular-devkit/core';
@ -40,6 +40,16 @@ export async function webpackFinal(baseConfig: webpack.Configuration, options: P
})
);
try {
require.resolve('@angular/animations');
} catch (e) {
webpackConfig.plugins.push(
new WebpackIgnorePlugin({
resourceRegExp: /@angular\/platform-browser\/animations$/,
})
);
}
return webpackConfig;
}

View File

@ -1,41 +0,0 @@
import { Meta, StoryObj, applicationConfig } from '@storybook/angular';
import { expect, userEvent, within } from '@storybook/test';
import { importProvidersFrom } from '@angular/core';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { OpenCloseComponent } from '../moduleMetadata/angular-src/open-close-component/open-close.component';
const meta: Meta = {
component: OpenCloseComponent,
decorators: [
applicationConfig({
providers: [importProvidersFrom(BrowserAnimationsModule)],
}),
],
parameters: {
chromatic: { delay: 100 },
},
};
export default meta;
type Story = StoryObj<typeof OpenCloseComponent>;
export const WithBrowserAnimations: Story = {
render: () => ({
template: `<app-open-close></app-open-close>`,
moduleMetadata: {
declarations: [OpenCloseComponent],
},
}),
play: async ({ canvasElement }) => {
const canvas = within(canvasElement);
const opened = canvas.getByText('The box is now Open!');
expect(opened).toBeDefined();
const submitButton = canvas.getByRole('button');
await userEvent.click(submitButton);
const closed = canvas.getByText('The box is now Closed!');
expect(closed).toBeDefined();
},
};

View File

@ -1,36 +0,0 @@
import { Meta, StoryObj } from '@storybook/angular';
import { expect, userEvent, within } from '@storybook/test';
import { importProvidersFrom } from '@angular/core';
import { NoopAnimationsModule } from '@angular/platform-browser/animations';
import { OpenCloseComponent } from '../moduleMetadata/angular-src/open-close-component/open-close.component';
const meta: Meta = {
component: OpenCloseComponent,
};
export default meta;
type Story = StoryObj<typeof OpenCloseComponent>;
export const WithNoopBrowserAnimations: Story = {
render: () => ({
template: `<app-open-close></app-open-close>`,
applicationConfig: {
providers: [importProvidersFrom(NoopAnimationsModule)],
},
moduleMetadata: {
declarations: [OpenCloseComponent],
},
}),
play: async ({ canvasElement }) => {
const canvas = within(canvasElement);
const opened = canvas.getByText('The box is now Open!');
expect(opened).toBeDefined();
const submitButton = canvas.getByRole('button');
await userEvent.click(submitButton);
const closed = canvas.getByText('The box is now Closed!');
expect(closed).toBeDefined();
},
};

View File

@ -1,13 +0,0 @@
:host {
display: block;
margin-top: 1rem;
}
.open-close-container {
margin-top: 1em;
border: 1px solid #dddddd;
padding: 20px 20px 0px 20px;
color: #000000;
font-weight: bold;
font-size: 20px;
}

View File

@ -1,7 +0,0 @@
<nav>
<button type="button" (click)="toggle()">Toggle Open/Close</button>
</nav>
<div [@openClose]="isOpen ? 'open' : 'closed'" class="open-close-container">
<p>The box is now {{ isOpen ? 'Open' : 'Closed' }}!</p>
</div>

View File

@ -1,39 +0,0 @@
import { Component } from '@angular/core';
import { trigger, state, style, transition, animate } from '@angular/animations';
@Component({
standalone: false,
selector: 'app-open-close',
animations: [
trigger('openClose', [
// ...
state(
'open',
style({
height: '200px',
opacity: 1,
backgroundColor: 'yellow',
})
),
state(
'closed',
style({
height: '100px',
opacity: 0.8,
backgroundColor: 'blue',
})
),
transition('open => closed', [animate('0.1s')]),
transition('closed => open', [animate('0.1s')]),
]),
],
templateUrl: 'open-close.component.html',
styleUrls: ['open-close.component.css'],
})
export class OpenCloseComponent {
isOpen = true;
toggle() {
this.isOpen = !this.isOpen;
}
}

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/ember",
"version": "8.6.0-beta.1",
"version": "8.6.0-beta.8",
"description": "Storybook for Ember: Develop Ember Component in isolation with Hot Reloading.",
"homepage": "https://github.com/storybookjs/storybook/tree/next/code/frameworks/ember",
"bugs": {

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/experimental-nextjs-vite",
"version": "8.6.0-beta.1",
"version": "8.6.0-beta.8",
"description": "Storybook for Next.js and Vite",
"keywords": [
"storybook",

View File

@ -96,7 +96,7 @@ export function composeStory<TArgs extends Args = Args>(
story as StoryAnnotationsOrFn<ReactRenderer, Args>,
componentAnnotations,
projectAnnotations,
INTERNAL_DEFAULT_PROJECT_ANNOTATIONS,
globalThis.globalProjectAnnotations ?? INTERNAL_DEFAULT_PROJECT_ANNOTATIONS,
exportsName
);
}

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/html-vite",
"version": "8.6.0-beta.1",
"version": "8.6.0-beta.8",
"description": "Storybook for HTML and Vite: Develop HTML in isolation with Hot Reloading.",
"keywords": [
"storybook"

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/html-webpack5",
"version": "8.6.0-beta.1",
"version": "8.6.0-beta.8",
"description": "Storybook for HTML: View HTML snippets in isolation with Hot Reloading.",
"keywords": [
"storybook"

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/nextjs",
"version": "8.6.0-beta.1",
"version": "8.6.0-beta.8",
"description": "Storybook for Next.js",
"keywords": [
"storybook",

View File

@ -96,7 +96,7 @@ export function composeStory<TArgs extends Args = Args>(
story as StoryAnnotationsOrFn<ReactRenderer, Args>,
componentAnnotations,
projectAnnotations,
INTERNAL_DEFAULT_PROJECT_ANNOTATIONS,
globalThis.globalProjectAnnotations ?? INTERNAL_DEFAULT_PROJECT_ANNOTATIONS,
exportsName
);
}

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/preact-vite",
"version": "8.6.0-beta.1",
"version": "8.6.0-beta.8",
"description": "Storybook for Preact and Vite: Develop Preact components in isolation with Hot Reloading.",
"keywords": [
"storybook"

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/preact-webpack5",
"version": "8.6.0-beta.1",
"version": "8.6.0-beta.8",
"description": "Storybook for Preact: Develop Preact Component in isolation.",
"keywords": [
"storybook"

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/react-native-web-vite",
"version": "8.6.0-beta.1",
"version": "8.6.0-beta.8",
"description": "Develop react-native components an isolated web environment with hot reloading.",
"keywords": [
"storybook"

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/react-vite",
"version": "8.6.0-beta.1",
"version": "8.6.0-beta.8",
"description": "Storybook for React and Vite: Develop React components in isolation with Hot Reloading.",
"keywords": [
"storybook"

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/react-webpack5",
"version": "8.6.0-beta.1",
"version": "8.6.0-beta.8",
"description": "Storybook for React: Develop React Component in isolation with Hot Reloading.",
"keywords": [
"storybook"

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/server-webpack5",
"version": "8.6.0-beta.1",
"version": "8.6.0-beta.8",
"description": "Storybook for Server: View HTML snippets from a server in isolation with Hot Reloading.",
"keywords": [
"storybook"

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/svelte-vite",
"version": "8.6.0-beta.1",
"version": "8.6.0-beta.8",
"description": "Storybook for Svelte and Vite: Develop Svelte components in isolation with Hot Reloading.",
"keywords": [
"storybook"

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/svelte-webpack5",
"version": "8.6.0-beta.1",
"version": "8.6.0-beta.8",
"description": "Storybook for Svelte: Develop Svelte Component in isolation with Hot Reloading.",
"keywords": [
"storybook"

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/sveltekit",
"version": "8.6.0-beta.1",
"version": "8.6.0-beta.8",
"description": "Storybook for SvelteKit",
"keywords": [
"storybook",

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/vue3-vite",
"version": "8.6.0-beta.1",
"version": "8.6.0-beta.8",
"description": "Storybook for Vue3 and Vite: Develop Vue3 components in isolation with Hot Reloading.",
"keywords": [
"storybook"

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/vue3-webpack5",
"version": "8.6.0-beta.1",
"version": "8.6.0-beta.8",
"description": "Storybook for Vue 3: Develop Vue 3 Components in isolation with Hot Reloading.",
"keywords": [
"storybook"

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/web-components-vite",
"version": "8.6.0-beta.1",
"version": "8.6.0-beta.8",
"description": "Storybook for web-components and Vite: Develop Web Components in isolation with Hot Reloading.",
"keywords": [
"storybook"

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/web-components-webpack5",
"version": "8.6.0-beta.1",
"version": "8.6.0-beta.8",
"description": "Storybook for web-components: View web components snippets in isolation with Hot Reloading.",
"keywords": [
"lit",

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/blocks",
"version": "8.6.0-beta.1",
"version": "8.6.0-beta.8",
"description": "Storybook Doc Blocks",
"keywords": [
"storybook"

View File

@ -1,6 +1,6 @@
{
"name": "sb",
"version": "8.6.0-beta.1",
"version": "8.6.0-beta.8",
"description": "Storybook CLI",
"keywords": [
"storybook"

Some files were not shown because too many files have changed in this diff Show More