diff --git a/CHANGELOG.prerelease.md b/CHANGELOG.prerelease.md index 05f683fc4658..81c30d40624b 100644 --- a/CHANGELOG.prerelease.md +++ b/CHANGELOG.prerelease.md @@ -1,3 +1,20 @@ +## 8.0.0-alpha.9 + +- AutoTitle: Fix case-insensitive trailing duplicate - [#25452](https://github.com/storybookjs/storybook/pull/25452), thanks [@ksugawara61](https://github.com/ksugawara61)! +- CLI: Add addon `remove` command - [#25538](https://github.com/storybookjs/storybook/pull/25538), thanks [@shilman](https://github.com/shilman)! +- CLI: Check optionalDependencies for storybook versions - [#25406](https://github.com/storybookjs/storybook/pull/25406), thanks [@reyronald](https://github.com/reyronald)! +- CLI: Fix using wrong package managers in existing projects - [#25474](https://github.com/storybookjs/storybook/pull/25474), thanks [@JReinhold](https://github.com/JReinhold)! +- CLI: Never prompt for ESLint plugin - [#25289](https://github.com/storybookjs/storybook/pull/25289), thanks [@shilman](https://github.com/shilman)! +- CLI: Versioned installation of monorepo packages - [#25517](https://github.com/storybookjs/storybook/pull/25517), thanks [@ndelangen](https://github.com/ndelangen)! +- CSF-tools: Allow type checking in storySort - [#25265](https://github.com/storybookjs/storybook/pull/25265), thanks [@honzahruby](https://github.com/honzahruby)! +- Core: Remove `storyStoreV7` feature flag - [#24658](https://github.com/storybookjs/storybook/pull/24658), thanks [@ndelangen](https://github.com/ndelangen)! +- Core: Remove deprecated createChannel APIs - [#25487](https://github.com/storybookjs/storybook/pull/25487), thanks [@yannbf](https://github.com/yannbf)! +- Doc blocks: Remove deprecated props from Primary block - [#25461](https://github.com/storybookjs/storybook/pull/25461), thanks [@yannbf](https://github.com/yannbf)! +- Node.js: Update version requirement to >= 18.0.0 - [#25516](https://github.com/storybookjs/storybook/pull/25516), thanks [@valentinpalkovic](https://github.com/valentinpalkovic)! +- Storysource: Fix import error - [#25391](https://github.com/storybookjs/storybook/pull/25391), thanks [@unional](https://github.com/unional)! +- UI: Fix sidebar top and bottom addon slots - [#25426](https://github.com/storybookjs/storybook/pull/25426), thanks [@ndelangen](https://github.com/ndelangen)! +- Webpack5: Remove babel and SWC compiler from builder - [#25379](https://github.com/storybookjs/storybook/pull/25379), thanks [@valentinpalkovic](https://github.com/valentinpalkovic)! + ## 8.0.0-alpha.8 - Addon Links: Remove LinkTo from direct import - [#25418](https://github.com/storybookjs/storybook/pull/25418), thanks [@yannbf](https://github.com/yannbf)! diff --git a/MIGRATION.md b/MIGRATION.md index 7d850150fc19..46f0a753c3c9 100644 --- a/MIGRATION.md +++ b/MIGRATION.md @@ -54,6 +54,7 @@ - [Deprecated docs parameters](#deprecated-docs-parameters) - [Description Doc block properties](#description-doc-block-properties) - [Manager API expandAll and collapseAll methods](#manager-api-expandall-and-collapseall-methods) + - [`Primary` Doc block properties](#primary-doc-block-properties) - [`createChannel` from `@storybook/postmessage` and `@storybook/channel-websocket`](#createchannel-from-storybookpostmessage-and--storybookchannel-websocket) - [From version 7.5.0 to 7.6.0](#from-version-750-to-760) - [CommonJS with Vite is deprecated](#commonjs-with-vite-is-deprecated) @@ -899,6 +900,10 @@ api.collapseAll() // becomes api.emit(STORIES_COLLAPSE_ALL) api.expandAll() // becomes api.emit(STORIES_EXPAND_ALL) ``` +#### `Primary` Doc block properties + +The `name` prop is now removed in favor of the `of` property. [More info](#doc-blocks). + #### `createChannel` from `@storybook/postmessage` and `@storybook/channel-websocket` The `createChannel` APIs from both `@storybook/channel-websocket` and `@storybook/postmessage` are now removed. Please use `createBrowserChannel` instead, from the `@storybook/channels` package. diff --git a/code/lib/cli/package.json b/code/lib/cli/package.json index 6cb280042f93..dda9d8e4b15e 100644 --- a/code/lib/cli/package.json +++ b/code/lib/cli/package.json @@ -89,7 +89,6 @@ "prompts": "^2.4.0", "read-pkg-up": "^7.0.1", "semver": "^7.3.7", - "simple-update-notifier": "^2.0.0", "strip-json-comments": "^3.0.1", "tempy": "^1.0.1", "tiny-invariant": "^1.3.1", diff --git a/code/lib/cli/src/generate.ts b/code/lib/cli/src/generate.ts index a91fd0517687..fa9acb1f7f09 100644 --- a/code/lib/cli/src/generate.ts +++ b/code/lib/cli/src/generate.ts @@ -11,6 +11,7 @@ import invariant from 'tiny-invariant'; import type { CommandOptions } from './generators/types'; import { initiate } from './initiate'; import { add } from './add'; +import { remove } from './remove'; import { migrate } from './migrate'; import { upgrade, type UpgradeOptions } from './upgrade'; import { sandbox } from './sandbox'; @@ -66,6 +67,14 @@ command('add ') .option('-s --skip-postinstall', 'Skip package specific postinstall config modifications') .action((addonName: string, options: any) => add(addonName, options)); +command('remove ') + .description('Remove an addon from your Storybook') + .option( + '--package-manager ', + 'Force package manager for installing dependencies' + ) + .action((addonName: string, options: any) => remove(addonName, options)); + command('upgrade') .description('Upgrade your Storybook packages to the latest') .option( diff --git a/code/lib/cli/src/generators/NEXTJS/index.ts b/code/lib/cli/src/generators/NEXTJS/index.ts index 40f91b3e8c66..fe6672b669a7 100644 --- a/code/lib/cli/src/generators/NEXTJS/index.ts +++ b/code/lib/cli/src/generators/NEXTJS/index.ts @@ -15,7 +15,7 @@ const generator: Generator = async (packageManager, npmOptions, options) => { 'react', { staticDir, - extraAddons: ['@storybook/addon-onboarding'], + extraAddons: ['@storybook/addon-onboarding@^1.0.0'], webpackCompiler: ({ builder }) => undefined, }, 'nextjs' diff --git a/code/lib/cli/src/generators/REACT/index.ts b/code/lib/cli/src/generators/REACT/index.ts index e19a55ce1adc..967ed7b5531b 100644 --- a/code/lib/cli/src/generators/REACT/index.ts +++ b/code/lib/cli/src/generators/REACT/index.ts @@ -11,7 +11,7 @@ const generator: Generator = async (packageManager, npmOptions, options) => { await baseGenerator(packageManager, npmOptions, options, 'react', { extraPackages, webpackCompiler: ({ builder }) => (builder === CoreBuilder.Webpack5 ? 'swc' : undefined), - extraAddons: ['@storybook/addon-onboarding'], + extraAddons: ['@storybook/addon-onboarding@^1.0.0'], }); }; diff --git a/code/lib/cli/src/generators/REACT_NATIVE/index.ts b/code/lib/cli/src/generators/REACT_NATIVE/index.ts index e3b8dcfa50c0..d87cd187e55b 100644 --- a/code/lib/cli/src/generators/REACT_NATIVE/index.ts +++ b/code/lib/cli/src/generators/REACT_NATIVE/index.ts @@ -30,14 +30,14 @@ const generator = async ( '@storybook/addon-controls@^6.5.16', ]; - const resolvedPackages = await packageManager.getVersionedPackages(packagesToResolve); + const versionedPackages = await packageManager.getVersionedPackages(packagesToResolve); const babelDependencies = await getBabelDependencies(packageManager, packageJson); const packages: string[] = []; packages.push(...babelDependencies); packages.push(...packagesWithFixedVersion); - packages.push(...resolvedPackages); + packages.push(...versionedPackages); if (missingReactDom && reactVersion) { packages.push(`react-dom@${reactVersion}`); } diff --git a/code/lib/cli/src/generators/WEBPACK_REACT/index.ts b/code/lib/cli/src/generators/WEBPACK_REACT/index.ts index d894be17b34e..a6f0293248f4 100644 --- a/code/lib/cli/src/generators/WEBPACK_REACT/index.ts +++ b/code/lib/cli/src/generators/WEBPACK_REACT/index.ts @@ -4,7 +4,7 @@ import type { Generator } from '../types'; const generator: Generator = async (packageManager, npmOptions, options) => { await baseGenerator(packageManager, npmOptions, options, 'react', { - extraAddons: ['@storybook/addon-onboarding'], + extraAddons: ['@storybook/addon-onboarding@^1.0.0'], webpackCompiler: ({ builder }) => (builder === CoreBuilder.Webpack5 ? 'swc' : undefined), }); }; diff --git a/code/lib/cli/src/generators/baseGenerator.ts b/code/lib/cli/src/generators/baseGenerator.ts index 2cf1b8c75687..a0bedbf55975 100644 --- a/code/lib/cli/src/generators/baseGenerator.ts +++ b/code/lib/cli/src/generators/baseGenerator.ts @@ -298,8 +298,6 @@ export async function baseGenerator( const versionedPackages = await packageManager.getVersionedPackages(packages as string[]); versionedPackagesSpinner.succeed(); - const depsToInstall = [...versionedPackages]; - try { if (process.env.CI !== 'true') { const { hasEslint, isStorybookPluginInstalled, eslintConfigFile } = await extractEslintInfo( @@ -307,7 +305,7 @@ export async function baseGenerator( ); if (hasEslint && !isStorybookPluginInstalled) { - depsToInstall.push('eslint-plugin-storybook'); + versionedPackages.push('eslint-plugin-storybook'); await configureEslintPlugin(eslintConfigFile ?? undefined, packageManager); } } @@ -315,12 +313,13 @@ export async function baseGenerator( // any failure regarding configuring the eslint plugin should not fail the whole generator } - if (depsToInstall.length > 0) { + if (versionedPackages.length > 0) { const addDependenciesSpinner = ora({ indent: 2, text: 'Installing Storybook dependencies', }).start(); - await packageManager.addDependencies({ ...npmOptions, packageJson }, depsToInstall); + + await packageManager.addDependencies({ ...npmOptions, packageJson }, versionedPackages); addDependenciesSpinner.succeed(); } diff --git a/code/lib/cli/src/helpers.ts b/code/lib/cli/src/helpers.ts index 33c7b6c6ccd9..ed54bd765986 100644 --- a/code/lib/cli/src/helpers.ts +++ b/code/lib/cli/src/helpers.ts @@ -295,7 +295,11 @@ export async function adjustTemplate(templatePath: string, templateData: Record< // Given a package.json, finds any official storybook package within it // and if it exists, returns the version of that package from the specified package.json export function getStorybookVersionSpecifier(packageJson: PackageJsonWithDepsAndDevDeps) { - const allDeps = { ...packageJson.dependencies, ...packageJson.devDependencies }; + const allDeps = { + ...packageJson.dependencies, + ...packageJson.devDependencies, + ...packageJson.optionalDependencies, + }; const storybookPackage = Object.keys(allDeps).find((name: string) => { return storybookMonorepoPackages[name as keyof typeof storybookMonorepoPackages]; }); diff --git a/code/lib/cli/src/initiate.ts b/code/lib/cli/src/initiate.ts index c0dbf5a3c7b3..f32b824ab97b 100644 --- a/code/lib/cli/src/initiate.ts +++ b/code/lib/cli/src/initiate.ts @@ -8,6 +8,7 @@ import { NxProjectDetectedError } from '@storybook/core-events/server-errors'; import dedent from 'ts-dedent'; import boxen from 'boxen'; +import { lt, prerelease } from 'semver'; import type { Builder } from './project_types'; import { installableProjectTypes, ProjectType } from './project_types'; import { detect, isStorybookInstantiated, detectLanguage, detectPnp } from './detect'; @@ -241,15 +242,33 @@ async function doInitiate( force: pkgMgr, }); - const welcomeMessage = 'storybook init - the simplest way to add a Storybook to your project.'; - logger.log(chalk.inverse(`\n ${welcomeMessage} \n`)); + const latestVersion = await packageManager.latestVersion('@storybook/cli'); + const currentVersion = versions['@storybook/cli']; + const isPrerelease = prerelease(currentVersion); + const isOutdated = lt(currentVersion, latestVersion); + const borderColor = isOutdated ? '#FC521F' : '#F1618C'; + + const messages = { + welcome: `Adding Storybook version ${chalk.bold(currentVersion)} to your project..`, + notLatest: chalk.red(dedent` + This version is behind the latest release, which is: ${chalk.bold(latestVersion)}! + You likely ran the init command through npx, which can use a locally cached version, to get the latest please run: + ${chalk.bold('npx storybook@latest init')} + + You may want to CTRL+C to stop, and run with the latest version instead. + `), + prelease: chalk.yellow('This is a pre-release version.'), + }; - // Update notify code. - const { default: updateNotifier } = await import('simple-update-notifier'); - await updateNotifier({ - pkg: pkg as any, - updateCheckInterval: 1000 * 60 * 60, // every hour (we could increase this later on.) - }); + logger.log( + boxen( + [messages.welcome] + .concat(isOutdated && !isPrerelease ? [messages.notLatest] : []) + .concat(isPrerelease ? [messages.prelease] : []) + .join('\n'), + { borderStyle: 'round', padding: 1, borderColor } + ) + ); // Check if the current directory is empty. if (options.force !== true && currentDirectoryIsEmpty(packageManager.type)) { diff --git a/code/lib/cli/src/js-package-manager/JsPackageManager.ts b/code/lib/cli/src/js-package-manager/JsPackageManager.ts index 5a3e82be3c43..17ec76ad34a3 100644 --- a/code/lib/cli/src/js-package-manager/JsPackageManager.ts +++ b/code/lib/cli/src/js-package-manager/JsPackageManager.ts @@ -330,13 +330,29 @@ export abstract class JsPackageManager { /** * Return an array of strings matching following format: `@` * + * For packages in the storybook monorepo, when the latest version is equal to the version of the current CLI + * the version is not added to the string. + * + * When a package is in the monorepo, and the version is not equal to the CLI version, the version is taken from the versions.ts file and added to the string. + * * @param packages */ public getVersionedPackages(packages: string[]): Promise { return Promise.all( packages.map(async (pkg) => { const [packageName, packageVersion] = getPackageDetails(pkg); - return `${packageName}@${await this.getVersion(packageName, packageVersion)}`; + const latestInRange = await this.latestVersion(packageName, packageVersion); + + const k = packageName as keyof typeof storybookPackagesVersions; + const currentVersion = storybookPackagesVersions[k]; + + if (currentVersion === latestInRange) { + return `${packageName}`; + } + if (currentVersion) { + return `${packageName}@${currentVersion}`; + } + return `${packageName}@^${latestInRange}`; }) ); } diff --git a/code/lib/cli/src/remove.ts b/code/lib/cli/src/remove.ts new file mode 100644 index 000000000000..47c556eb578f --- /dev/null +++ b/code/lib/cli/src/remove.ts @@ -0,0 +1,46 @@ +import { getStorybookInfo } from '@storybook/core-common'; +import { readConfig, writeConfig } from '@storybook/csf-tools'; +import dedent from 'ts-dedent'; + +import { JsPackageManagerFactory, type PackageManagerName } from './js-package-manager'; + +const logger = console; + +/** + * Remove the given addon package and remove it from main.js + * + * Usage: + * - sb remove @storybook/addon-links + */ +export async function remove(addon: string, options: { packageManager: PackageManagerName }) { + const { packageManager: pkgMgr } = options; + + const packageManager = JsPackageManagerFactory.getPackageManager({ force: pkgMgr }); + const packageJson = await packageManager.retrievePackageJson(); + const { mainConfig, configDir } = getStorybookInfo(packageJson); + + if (typeof configDir === 'undefined') { + throw new Error(dedent` + Unable to find storybook config directory + `); + } + + if (!mainConfig) { + logger.error('Unable to find storybook main.js config'); + return; + } + const main = await readConfig(mainConfig); + + // remove from package.json + logger.log(`Uninstalling ${addon}`); + await packageManager.removeDependencies({ packageJson }, [addon]); + + // add to main.js + logger.log(`Removing '${addon}' from main.js addons field.`); + try { + main.removeEntryFromArray(['addons'], addon); + await writeConfig(main); + } catch (err) { + logger.warn(`Failed to remove '${addon}' from main.js addons field.`); + } +} diff --git a/code/lib/csf-tools/src/ConfigFile.test.ts b/code/lib/csf-tools/src/ConfigFile.test.ts index 2ae59f8a75ac..5fc75ff41f26 100644 --- a/code/lib/csf-tools/src/ConfigFile.test.ts +++ b/code/lib/csf-tools/src/ConfigFile.test.ts @@ -1139,4 +1139,74 @@ describe('ConfigFile', () => { `); }); }); + + describe('removeEntryFromArray', () => { + it('removes a string literal entry', () => { + const source = dedent` + export default { + addons: ['a', 'b', 'c'], + } + `; + const config = loadConfig(source).parse(); + config.removeEntryFromArray(['addons'], 'b'); + expect(config.getFieldValue(['addons'])).toMatchInlineSnapshot(`a,c`); + }); + + it('removes a preset-style object entry', () => { + const source = dedent` + export default { + addons: ['a', { name: 'b', options: {} }, 'c'], + } + `; + const config = loadConfig(source).parse(); + config.removeEntryFromArray(['addons'], 'b'); + expect(config.getFieldValue(['addons'])).toMatchInlineSnapshot(`a,c`); + }); + + it('removes a pnp-wrapped string entry', () => { + const source = dedent` + export default { + addons: ['a', getAbsolutePath('b'), 'c'], + } + `; + const config = loadConfig(source).parse(); + config.removeEntryFromArray(['addons'], 'b'); + expect(config.getFieldValue(['addons'])).toMatchInlineSnapshot(`a,c`); + }); + + it('removes a pnp-wrapped object entry', () => { + const source = dedent` + export default { + addons: ['a', { name: getAbsolutePath('b'), options: {} }, 'c'], + } + `; + const config = loadConfig(source).parse(); + config.removeEntryFromArray(['addons'], 'b'); + expect(config.getFieldValue(['addons'])).toMatchInlineSnapshot(`a,c`); + }); + + it('throws when entry is missing', () => { + const source = dedent` + export default { + addons: ['a', { name: 'b', options: {} }, 'c'], + } + `; + const config = loadConfig(source).parse(); + expect(() => config.removeEntryFromArray(['addons'], 'x')).toThrowErrorMatchingInlineSnapshot( + `Error: Could not find 'x' in array at 'addons'` + ); + }); + + it('throws when target array is not an arral', () => { + const source = dedent` + export default { + addons: {}, + } + `; + const config = loadConfig(source).parse(); + expect(() => config.removeEntryFromArray(['addons'], 'x')).toThrowErrorMatchingInlineSnapshot( + `Error: Expected array at 'addons', got 'ObjectExpression'` + ); + }); + }); }); diff --git a/code/lib/csf-tools/src/ConfigFile.ts b/code/lib/csf-tools/src/ConfigFile.ts index eb2921b4e06d..410bbcc1fee7 100644 --- a/code/lib/csf-tools/src/ConfigFile.ts +++ b/code/lib/csf-tools/src/ConfigFile.ts @@ -390,6 +390,16 @@ export class ConfigFile { return pathNames; } + _getPnpWrappedValue(node: t.Node) { + if (t.isCallExpression(node)) { + const arg = node.arguments[0]; + if (t.isStringLiteral(arg)) { + return arg.value; + } + } + return undefined; + } + /** * Given a node and a fallback property, returns a **non-evaluated** string value of the node. * 1. { node: 'value' } @@ -409,6 +419,8 @@ export class ConfigFile { ) { if (t.isStringLiteral(prop.value)) { value = prop.value.value; + } else { + value = this._getPnpWrappedValue(prop.value); } } @@ -506,6 +518,34 @@ export class ConfigFile { } } + /** + * Specialized helper to remove addons or other array entries + * that can either be strings or objects with a name property. + */ + removeEntryFromArray(path: string[], value: string) { + const current = this.getFieldNode(path); + if (!current) return; + if (t.isArrayExpression(current)) { + const index = current.elements.findIndex((element) => { + if (t.isStringLiteral(element)) { + return element.value === value; + } + if (t.isObjectExpression(element)) { + const name = this._getPresetValue(element, 'name'); + return name === value; + } + return this._getPnpWrappedValue(element as t.Node) === value; + }); + if (index >= 0) { + current.elements.splice(index, 1); + } else { + throw new Error(`Could not find '${value}' in array at '${path.join('.')}'`); + } + } else { + throw new Error(`Expected array at '${path.join('.')}', got '${current.type}'`); + } + } + _inferQuotes() { if (!this._quotes) { // first 500 tokens for efficiency diff --git a/code/lib/preview-api/src/modules/preview-web/docs-context/DocsContext.ts b/code/lib/preview-api/src/modules/preview-web/docs-context/DocsContext.ts index 40ea0ccbaa03..da41240756d5 100644 --- a/code/lib/preview-api/src/modules/preview-web/docs-context/DocsContext.ts +++ b/code/lib/preview-api/src/modules/preview-web/docs-context/DocsContext.ts @@ -201,6 +201,10 @@ export class DocsContext implements DocsContextProps return this.componentStoriesValue; }; + componentStoriesFromCSFFile = (csfFile: CSFFile) => { + return this.store.componentStoriesFromCSFFile({ csfFile }); + }; + storyById = (storyId?: StoryId) => { if (!storyId) { if (!this.primaryStory) diff --git a/code/lib/types/src/modules/docs.ts b/code/lib/types/src/modules/docs.ts index ba52f2b7c139..571478250143 100644 --- a/code/lib/types/src/modules/docs.ts +++ b/code/lib/types/src/modules/docs.ts @@ -83,6 +83,11 @@ export interface DocsContextProps { */ componentStories: () => PreparedStory[]; + /** + * Syncronously find all stories by CSF file. + */ + componentStoriesFromCSFFile: (csfFile: CSFFile) => PreparedStory[]; + /** * Get the story context of the referenced story. */ diff --git a/code/package.json b/code/package.json index e41a777c6d44..1e2cd8bee675 100644 --- a/code/package.json +++ b/code/package.json @@ -298,5 +298,6 @@ "Dependency Upgrades" ] ] - } + }, + "deferredNextVersion": "8.0.0-alpha.9" } diff --git a/code/ui/blocks/src/blocks/Primary.stories.tsx b/code/ui/blocks/src/blocks/Primary.stories.tsx index 7c4747d53a3b..4412881fd702 100644 --- a/code/ui/blocks/src/blocks/Primary.stories.tsx +++ b/code/ui/blocks/src/blocks/Primary.stories.tsx @@ -26,26 +26,6 @@ export const WithoutToolbar: Story = { }, }; -export const DefaultWithName: Story = { - name: 'Name', - args: { - name: 'Primary', - }, - parameters: { - relativeCsfPaths: ['../examples/Button.stories'], - }, -}; - -export const WithoutToolbarWithName: Story = { - name: 'Name Without Toolbar', - args: { - name: 'Without Toolbar', - }, - parameters: { - relativeCsfPaths: ['../examples/StoriesParameters.stories'], - }, -}; - export const DefaultWithOf: Story = { name: 'Of', args: { diff --git a/code/ui/blocks/src/blocks/Primary.tsx b/code/ui/blocks/src/blocks/Primary.tsx index 7d1364f2dc51..7a7cd53fbe36 100644 --- a/code/ui/blocks/src/blocks/Primary.tsx +++ b/code/ui/blocks/src/blocks/Primary.tsx @@ -1,17 +1,11 @@ import type { FC } from 'react'; import React, { useContext } from 'react'; -import dedent from 'ts-dedent'; -import { deprecate } from '@storybook/client-logger'; import type { Of } from './useOf'; import { useOf } from './useOf'; -import { DocsContext } from './DocsContext'; import { DocsStory } from './DocsStory'; +import { DocsContext } from './DocsContext'; interface PrimaryProps { - /** - * @deprecated Primary block should only be used to render the primary story, which is automatically found. - */ - name?: string; /** * Specify where to get the primary story from. */ @@ -19,32 +13,17 @@ interface PrimaryProps { } export const Primary: FC = (props) => { - const { name, of } = props; - + const { of } = props; if ('of' in props && of === undefined) { throw new Error('Unexpected `of={undefined}`, did you mistype a CSF file reference?'); } - const docsContext = useContext(DocsContext); + const { csfFile } = useOf(of || 'meta', ['meta']); + const context = useContext(DocsContext); - let story; - if (of) { - const resolvedOf = useOf(of || 'meta', ['meta']); - story = resolvedOf.csfFile.stories[0] || null; - } - - if (!story) { - const storyId = name && docsContext.storyIdByName(name); - story = docsContext.storyById(storyId); - } - - if (name) { - deprecate(dedent`\`name\` prop is deprecated on the Primary block. - The Primary block should only be used to render the primary story, which is automatically found. - `); - } + const primaryStory = context.componentStoriesFromCSFFile(csfFile)[0]; - return story ? ( - + return primaryStory ? ( + ) : null; }; diff --git a/code/yarn.lock b/code/yarn.lock index e035a0f0eb42..e4e15dc7df5c 100644 --- a/code/yarn.lock +++ b/code/yarn.lock @@ -5313,7 +5313,6 @@ __metadata: prompts: "npm:^2.4.0" read-pkg-up: "npm:^7.0.1" semver: "npm:^7.3.7" - simple-update-notifier: "npm:^2.0.0" slash: "npm:^5.0.0" strip-json-comments: "npm:^3.1.1" tempy: "npm:^1.0.1" @@ -25995,15 +25994,6 @@ __metadata: languageName: node linkType: hard -"simple-update-notifier@npm:^2.0.0": - version: 2.0.0 - resolution: "simple-update-notifier@npm:2.0.0" - dependencies: - semver: "npm:^7.5.3" - checksum: 2a00bd03bfbcbf8a737c47ab230d7920f8bfb92d1159d421bdd194479f6d01ebc995d13fbe13d45dace23066a78a3dc6642999b4e3b38b847e6664191575b20c - languageName: node - linkType: hard - "sisteransi@npm:^1.0.5": version: 1.0.5 resolution: "sisteransi@npm:1.0.5" diff --git a/docs/api/doc-block-primary.md b/docs/api/doc-block-primary.md index c4993c2db2a0..4214dcc2c1bd 100644 --- a/docs/api/doc-block-primary.md +++ b/docs/api/doc-block-primary.md @@ -34,11 +34,3 @@ import { Primary } from '@storybook/blocks'; Type: CSF file exports Specifies which CSF file is used to find the first story, which is then rendered by this block. Pass the full set of exports from the CSF file (not the default export!). - -### `name` - -(⛔️ **Deprecated**) - -Type: `string` - -Primary block should only be used to render the primary story, which is automatically found. diff --git a/docs/versions/next.json b/docs/versions/next.json index 7de16aa408a1..9cbedfd1eb57 100644 --- a/docs/versions/next.json +++ b/docs/versions/next.json @@ -1 +1 @@ -{"version":"8.0.0-alpha.8","info":{"plain":"- Addon Links: Remove LinkTo from direct import - [#25418](https://github.com/storybookjs/storybook/pull/25418), thanks [@yannbf](https://github.com/yannbf)!\n- Addon docs: Remove deprecated parameters - [#25469](https://github.com/storybookjs/storybook/pull/25469), thanks [@yannbf](https://github.com/yannbf)!\n- Builder Vite: Remove StorybookViteConfig type in favor of StorybookConfig - [#25441](https://github.com/storybookjs/storybook/pull/25441), thanks [@yannbf](https://github.com/yannbf)!\n- Core: Error on explicit actions while rendering or playing - [#25238](https://github.com/storybookjs/storybook/pull/25238), thanks [@kasperpeulen](https://github.com/kasperpeulen)!\n- Core: Remove collapseAll and expandAll methods - [#25486](https://github.com/storybookjs/storybook/pull/25486), thanks [@yannbf](https://github.com/yannbf)!\n- Core: Remove storyIndexers in favor of experimental_indexers - [#25468](https://github.com/storybookjs/storybook/pull/25468), thanks [@yannbf](https://github.com/yannbf)!\n- Core: Remove unused staticDir type - [#25415](https://github.com/storybookjs/storybook/pull/25415), thanks [@yannbf](https://github.com/yannbf)!\n- Doc blocks: Remove deprecated props from Description block - [#25457](https://github.com/storybookjs/storybook/pull/25457), thanks [@yannbf](https://github.com/yannbf)!\n- Manager API: Remove deprecated navigateToSettingsPage method - [#25467](https://github.com/storybookjs/storybook/pull/25467), thanks [@yannbf](https://github.com/yannbf)!\n- React: Remove deprecated setGlobalConfig portable stories api - [#25442](https://github.com/storybookjs/storybook/pull/25442), thanks [@yannbf](https://github.com/yannbf)!\n- TypeScript: Remove deprecated addons module types - [#25485](https://github.com/storybookjs/storybook/pull/25485), thanks [@yannbf](https://github.com/yannbf)!\n- Types: Remove DecoratorFn, Story, ComponentStory, ComponentStoryObj, ComponentStoryFn and ComponentMeta types - [#25477](https://github.com/storybookjs/storybook/pull/25477), thanks [@yannbf](https://github.com/yannbf)!\n- Types: Remove Framework in favor of Renderer types - [#25476](https://github.com/storybookjs/storybook/pull/25476), thanks [@yannbf](https://github.com/yannbf)!\n- UI: Remove deprecated WithTooltip props - [#25440](https://github.com/storybookjs/storybook/pull/25440), thanks [@yannbf](https://github.com/yannbf)!"}} +{"version":"8.0.0-alpha.9","info":{"plain":"- AutoTitle: Fix case-insensitive trailing duplicate - [#25452](https://github.com/storybookjs/storybook/pull/25452), thanks [@ksugawara61](https://github.com/ksugawara61)!\n- CLI: Add addon `remove` command - [#25538](https://github.com/storybookjs/storybook/pull/25538), thanks [@shilman](https://github.com/shilman)!\n- CLI: Check optionalDependencies for storybook versions - [#25406](https://github.com/storybookjs/storybook/pull/25406), thanks [@reyronald](https://github.com/reyronald)!\n- CLI: Fix using wrong package managers in existing projects - [#25474](https://github.com/storybookjs/storybook/pull/25474), thanks [@JReinhold](https://github.com/JReinhold)!\n- CLI: Never prompt for ESLint plugin - [#25289](https://github.com/storybookjs/storybook/pull/25289), thanks [@shilman](https://github.com/shilman)!\n- CLI: Versioned installation of monorepo packages - [#25517](https://github.com/storybookjs/storybook/pull/25517), thanks [@ndelangen](https://github.com/ndelangen)!\n- CSF-tools: Allow type checking in storySort - [#25265](https://github.com/storybookjs/storybook/pull/25265), thanks [@honzahruby](https://github.com/honzahruby)!\n- Core: Remove `storyStoreV7` feature flag - [#24658](https://github.com/storybookjs/storybook/pull/24658), thanks [@ndelangen](https://github.com/ndelangen)!\n- Core: Remove deprecated createChannel APIs - [#25487](https://github.com/storybookjs/storybook/pull/25487), thanks [@yannbf](https://github.com/yannbf)!\n- Doc blocks: Remove deprecated props from Primary block - [#25461](https://github.com/storybookjs/storybook/pull/25461), thanks [@yannbf](https://github.com/yannbf)!\n- Node.js: Update version requirement to >= 18.0.0 - [#25516](https://github.com/storybookjs/storybook/pull/25516), thanks [@valentinpalkovic](https://github.com/valentinpalkovic)!\n- Storysource: Fix import error - [#25391](https://github.com/storybookjs/storybook/pull/25391), thanks [@unional](https://github.com/unional)!\n- UI: Fix sidebar top and bottom addon slots - [#25426](https://github.com/storybookjs/storybook/pull/25426), thanks [@ndelangen](https://github.com/ndelangen)!\n- Webpack5: Remove babel and SWC compiler from builder - [#25379](https://github.com/storybookjs/storybook/pull/25379), thanks [@valentinpalkovic](https://github.com/valentinpalkovic)!"}}