From f0ac1685f78f95689784f16d68233673437ba001 Mon Sep 17 00:00:00 2001 From: Valentin Palkovic Date: Tue, 25 Mar 2025 15:31:53 +0100 Subject: [PATCH 01/37] Remove deprecated addon APIs --- code/core/src/manager-api/lib/addons.ts | 6 --- code/core/src/manager-api/modules/addons.ts | 4 +- .../manager/components/sidebar/Heading.tsx | 4 -- .../components/sidebar/Sidebar.stories.tsx | 2 - .../manager/components/sidebar/Sidebar.tsx | 5 +-- code/core/src/manager/container/Sidebar.tsx | 5 --- code/core/src/types/modules/addons.ts | 43 +------------------ 7 files changed, 3 insertions(+), 66 deletions(-) diff --git a/code/core/src/manager-api/lib/addons.ts b/code/core/src/manager-api/lib/addons.ts index 75486a0b25a..f6911eaef29 100644 --- a/code/core/src/manager-api/lib/addons.ts +++ b/code/core/src/manager-api/lib/addons.ts @@ -8,8 +8,6 @@ import type { Addon_Elements, Addon_Loaders, Addon_PageType, - Addon_SidebarBottomType, - Addon_SidebarTopType, Addon_TestProviderType, Addon_Type, Addon_Types, @@ -70,8 +68,6 @@ export class AddonStore { T extends | Addon_Types | Addon_TypesEnum.experimental_PAGE - | Addon_TypesEnum.experimental_SIDEBAR_BOTTOM - | Addon_TypesEnum.experimental_SIDEBAR_TOP | Addon_TypesEnum.experimental_TEST_PROVIDER, >(type: T): Addon_Collection | any { if (!this.elements[type]) { @@ -91,8 +87,6 @@ export class AddonStore { id: string, addon: | Addon_BaseType - | Omit - | Omit | Omit | Omit | Omit diff --git a/code/core/src/manager-api/modules/addons.ts b/code/core/src/manager-api/modules/addons.ts index 5382013b0b0..55ed5a55936 100644 --- a/code/core/src/manager-api/modules/addons.ts +++ b/code/core/src/manager-api/modules/addons.ts @@ -29,9 +29,7 @@ export interface SubAPI { T extends | Addon_Types | Addon_TypesEnum.experimental_PAGE - | Addon_TypesEnum.experimental_SIDEBAR_BOTTOM - | Addon_TypesEnum.experimental_TEST_PROVIDER - | Addon_TypesEnum.experimental_SIDEBAR_TOP = Addon_Types, + | Addon_TypesEnum.experimental_TEST_PROVIDER, >( type: T ) => Addon_Collection; diff --git a/code/core/src/manager/components/sidebar/Heading.tsx b/code/core/src/manager/components/sidebar/Heading.tsx index 99be57270b3..b70c5682a05 100644 --- a/code/core/src/manager/components/sidebar/Heading.tsx +++ b/code/core/src/manager/components/sidebar/Heading.tsx @@ -2,7 +2,6 @@ import type { ComponentProps, FC } from 'react'; import React from 'react'; import { Button } from 'storybook/internal/components'; -import type { Addon_SidebarTopType } from 'storybook/internal/types'; import { styled } from 'storybook/theming'; @@ -13,7 +12,6 @@ import { SidebarMenu } from './Menu'; export interface HeadingProps { menuHighlighted?: boolean; menu: MenuList; - extra: Addon_SidebarTopType[]; skipLinkHref?: string; isLoading: boolean; onMenuClick?: SidebarMenuProps['onClick']; @@ -83,7 +81,6 @@ export const Heading: FC> = menuHighlighted = false, menu, skipLinkHref, - extra, isLoading, onMenuClick, ...props @@ -102,7 +99,6 @@ export const Heading: FC> = - {isLoading ? null : extra.map(({ id, render: Render }) => )} ); diff --git a/code/core/src/manager/components/sidebar/Sidebar.stories.tsx b/code/core/src/manager/components/sidebar/Sidebar.stories.tsx index 7606d5ef6ea..0afbac8da6f 100644 --- a/code/core/src/manager/components/sidebar/Sidebar.stories.tsx +++ b/code/core/src/manager/components/sidebar/Sidebar.stories.tsx @@ -1,6 +1,5 @@ import React from 'react'; -import { type Addon_SidebarTopType } from 'storybook/internal/types'; import type { StatusesByStoryIdAndTypeId } from 'storybook/internal/types'; import type { Meta, StoryObj } from '@storybook/react-vite'; @@ -68,7 +67,6 @@ const meta = { args: { previewInitialized: true, menu, - extra: [] as Addon_SidebarTopType[], index: index, indexJson: { entries: { diff --git a/code/core/src/manager/components/sidebar/Sidebar.tsx b/code/core/src/manager/components/sidebar/Sidebar.tsx index 55544a2d3fe..f9de6527207 100644 --- a/code/core/src/manager/components/sidebar/Sidebar.tsx +++ b/code/core/src/manager/components/sidebar/Sidebar.tsx @@ -7,7 +7,7 @@ import { TooltipNote, WithTooltip, } from 'storybook/internal/components'; -import type { API_LoadedRefData, Addon_SidebarTopType, StoryIndex } from 'storybook/internal/types'; +import type { API_LoadedRefData, StoryIndex } from 'storybook/internal/types'; import type { StatusesByStoryIdAndTypeId } from 'storybook/internal/types'; import { global } from '@storybook/global'; @@ -117,7 +117,6 @@ export interface SidebarProps extends API_LoadedRefData { refs: State['refs']; allStatuses: StatusesByStoryIdAndTypeId; menu: any[]; - extra: Addon_SidebarTopType[]; storyId?: string; refId?: string; menuHighlighted?: boolean; @@ -137,7 +136,6 @@ export const Sidebar = React.memo(function Sidebar({ allStatuses, previewInitialized, menu, - extra, menuHighlighted = false, enableShortcuts = true, isDevelopment = global.CONFIG_TYPE === 'DEVELOPMENT', @@ -162,7 +160,6 @@ export const Sidebar = React.memo(function Sidebar({ className="sidebar-header" menuHighlighted={menuHighlighted} menu={menu} - extra={extra} skipLinkHref="#storybook-preview-wrapper" isLoading={isLoading} onMenuClick={onMenuClick} diff --git a/code/core/src/manager/container/Sidebar.tsx b/code/core/src/manager/container/Sidebar.tsx index a18bbc99939..a3b7357b271 100755 --- a/code/core/src/manager/container/Sidebar.tsx +++ b/code/core/src/manager/container/Sidebar.tsx @@ -46,10 +46,6 @@ const Sidebar = React.memo(function Sideber({ onMenuClick }: SidebarProps) { const whatsNewNotificationsEnabled = state.whatsNewData?.status === 'SUCCESS' && !state.disableWhatsNewNotifications; - const topItems = api.getElements(Addon_TypesEnum.experimental_SIDEBAR_TOP); - // eslint-disable-next-line react-hooks/exhaustive-deps - const top = useMemo(() => Object.values(topItems), [Object.keys(topItems).join('')]); - return { title: name, url, @@ -64,7 +60,6 @@ const Sidebar = React.memo(function Sideber({ onMenuClick }: SidebarProps) { menu, menuHighlighted: whatsNewNotificationsEnabled && api.isWhatsNewUnread(), enableShortcuts, - extra: top, }; }; diff --git a/code/core/src/types/modules/addons.ts b/code/core/src/types/modules/addons.ts index 981a7566cf7..aa923505097 100644 --- a/code/core/src/types/modules/addons.ts +++ b/code/core/src/types/modules/addons.ts @@ -26,10 +26,7 @@ import type { IndexEntry } from './indexer'; export type Addon_Types = Exclude< Addon_TypesEnum, - | Addon_TypesEnum.experimental_PAGE - | Addon_TypesEnum.experimental_SIDEBAR_BOTTOM - | Addon_TypesEnum.experimental_TEST_PROVIDER - | Addon_TypesEnum.experimental_SIDEBAR_TOP + Addon_TypesEnum.experimental_PAGE | Addon_TypesEnum.experimental_TEST_PROVIDER >; export interface Addon_ArgType extends InputType { @@ -328,8 +325,6 @@ export type Addon_Type = | Addon_BaseType | Addon_PageType | Addon_WrapperType - | Addon_SidebarBottomType - | Addon_SidebarTopType | Addon_TestProviderType; export interface Addon_BaseType { /** @@ -350,8 +345,6 @@ export interface Addon_BaseType { Addon_Types, | Addon_TypesEnum.PREVIEW | Addon_TypesEnum.experimental_PAGE - | Addon_TypesEnum.experimental_SIDEBAR_BOTTOM - | Addon_TypesEnum.experimental_SIDEBAR_TOP | Addon_TypesEnum.experimental_TEST_PROVIDER >; /** @@ -448,24 +441,6 @@ export interface Addon_WrapperType { >; } -/** @deprecated This doesn't do anything anymore and will be removed in Storybook 9.0. */ -export interface Addon_SidebarBottomType { - type: Addon_TypesEnum.experimental_SIDEBAR_BOTTOM; - /** The unique id of the tool. */ - id: string; - /** A React.FunctionComponent. */ - render: FC; -} - -/** @deprecated This will be removed in Storybook 9.0. */ -export interface Addon_SidebarTopType { - type: Addon_TypesEnum.experimental_SIDEBAR_TOP; - /** The unique id of the tool. */ - id: string; - /** A React.FunctionComponent. */ - render: FC; -} - export interface Addon_TestProviderType< Details extends { [key: string]: any } = NonNullable, > { @@ -508,16 +483,12 @@ type Addon_TypeBaseNames = Exclude< Addon_TypesEnum, | Addon_TypesEnum.PREVIEW | Addon_TypesEnum.experimental_PAGE - | Addon_TypesEnum.experimental_SIDEBAR_BOTTOM - | Addon_TypesEnum.experimental_SIDEBAR_TOP | Addon_TypesEnum.experimental_TEST_PROVIDER >; export interface Addon_TypesMapping extends Record { [Addon_TypesEnum.PREVIEW]: Addon_WrapperType; [Addon_TypesEnum.experimental_PAGE]: Addon_PageType; - [Addon_TypesEnum.experimental_SIDEBAR_BOTTOM]: Addon_SidebarBottomType; - [Addon_TypesEnum.experimental_SIDEBAR_TOP]: Addon_SidebarTopType; [Addon_TypesEnum.experimental_TEST_PROVIDER]: Addon_TestProviderType; } @@ -570,18 +541,6 @@ export enum Addon_TypesEnum { * @unstable */ experimental_PAGE = 'page', - /** - * This adds items in the bottom of the sidebar. - * - * @deprecated This doesn't do anything anymore and will be removed in Storybook 9.0. - */ - experimental_SIDEBAR_BOTTOM = 'sidebar-bottom', - /** - * This adds items in the top of the sidebar. - * - * @deprecated This will be removed in Storybook 9.0. - */ - experimental_SIDEBAR_TOP = 'sidebar-top', /** This adds items to the Testing Module in the sidebar. */ experimental_TEST_PROVIDER = 'test-provider', } From dc80bce3a9a843dc65a7aadb64314d105b3a55a4 Mon Sep 17 00:00:00 2001 From: Valentin Palkovic Date: Tue, 25 Mar 2025 15:35:01 +0100 Subject: [PATCH 02/37] Remove support for old icon format --- .../NotificationItem.stories.tsx | 17 -------- .../notifications/NotificationItem.tsx | 41 ++++++------------- code/core/src/types/modules/api.ts | 13 +----- 3 files changed, 14 insertions(+), 57 deletions(-) diff --git a/code/core/src/manager/components/notifications/NotificationItem.stories.tsx b/code/core/src/manager/components/notifications/NotificationItem.stories.tsx index e5938424a9a..5df7f31e2b9 100644 --- a/code/core/src/manager/components/notifications/NotificationItem.stories.tsx +++ b/code/core/src/manager/components/notifications/NotificationItem.stories.tsx @@ -274,20 +274,3 @@ export const AccessibilityGoldIconLongHeadLineNoSubHeadline: Story = { }, }, }; - -export const WithOldIconFormat: Story = { - args: { - notification: { - id: '13', - onClear, - content: { - headline: 'Storybook notifications has a accessibility icon it can be any color!', - }, - icon: { - name: 'accessibility', - color: 'gold', - }, - link: undefined, - }, - }, -}; diff --git a/code/core/src/manager/components/notifications/NotificationItem.tsx b/code/core/src/manager/components/notifications/NotificationItem.tsx index 22410e1c8ca..286578dbd10 100644 --- a/code/core/src/manager/components/notifications/NotificationItem.tsx +++ b/code/core/src/manager/components/notifications/NotificationItem.tsx @@ -1,15 +1,14 @@ import type { FC, SyntheticEvent } from 'react'; import React, { useCallback, useEffect, useRef } from 'react'; -import type { IconsProps } from 'storybook/internal/components'; -import { IconButton, Icons } from 'storybook/internal/components'; +import { IconButton } from 'storybook/internal/components'; import { Link } from 'storybook/internal/router'; import { CloseAltIcon } from '@storybook/icons'; import { transparentize } from 'polished'; import { type State } from 'storybook/manager-api'; -import { keyframes, styled, useTheme } from 'storybook/theming'; +import { keyframes, styled } from 'storybook/theming'; import { MEDIA_DESKTOP_BREAKPOINT } from '../../constants'; @@ -133,31 +132,17 @@ const SubHeadline = styled.div(({ theme }) => ({ const ItemContent: FC> = ({ icon, content: { headline, subHeadline }, -}) => { - const theme = useTheme(); - const defaultColor = theme.base === 'dark' ? theme.color.mediumdark : theme.color.mediumlight; - - return ( - <> - {!icon || ( - - {React.isValidElement(icon) - ? icon - : typeof icon === 'object' && - 'name' in icon && ( - - )} - - )} - - - {headline} - - {subHeadline && {subHeadline}} - - - ); -}; +}) => ( + <> + {!icon || {icon}} + + + {headline} + + {subHeadline && {subHeadline}} + + +); const DismissButtonWrapper = styled(IconButton)(({ theme }) => ({ width: 28, diff --git a/code/core/src/types/modules/api.ts b/code/core/src/types/modules/api.ts index f5e2d6f3210..9d70dd48b51 100644 --- a/code/core/src/types/modules/api.ts +++ b/code/core/src/types/modules/api.ts @@ -88,8 +88,6 @@ export interface API_Layout { panelPosition: API_PanelPositions; showTabs: boolean; showToolbar: boolean; - /** @deprecated, will be removed in 8.0 - this API no longer works */ - isToolshown?: boolean; } export interface API_UI { @@ -120,14 +118,6 @@ interface OnClickOptions { onDismiss: () => void; } -/** - * @deprecated Use ReactNode for the icon instead. - * @see https://github.com/storybookjs/storybook/blob/next/MIGRATION.md#icons-is-deprecated - */ -interface DeprecatedIconType { - name: string; - color?: string; -} export interface API_Notification { id: string; content: { @@ -136,8 +126,7 @@ export interface API_Notification { }; duration?: number; link?: string; - // TODO: Remove DeprecatedIconType in 9.0 - icon?: React.ReactNode | DeprecatedIconType; + icon?: React.ReactNode; onClear?: (options: OnClearOptions) => void; onClick?: (options: OnClickOptions) => void; } From adbd8d21e986dd8e09c4e79a3bb2da574e5c5f31 Mon Sep 17 00:00:00 2001 From: Valentin Palkovic Date: Tue, 25 Mar 2025 15:35:43 +0100 Subject: [PATCH 03/37] Remove deprecated serverChannel property from API_Provider interface --- code/core/src/types/modules/api.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/code/core/src/types/modules/api.ts b/code/core/src/types/modules/api.ts index 9d70dd48b51..b418ba48ebd 100644 --- a/code/core/src/types/modules/api.ts +++ b/code/core/src/types/modules/api.ts @@ -38,8 +38,6 @@ export interface API_ProviderData { export interface API_Provider { channel?: Channel; - /** @deprecated Will be removed in 8.0, please use channel instead */ - serverChannel?: Channel; renderPreview?: API_IframeRenderer; handleAPI(api: API): void; getConfig(): { From 4c5675eed068d32668945df31429aeaf07f0c68f Mon Sep 17 00:00:00 2001 From: Valentin Palkovic Date: Tue, 25 Mar 2025 15:36:47 +0100 Subject: [PATCH 04/37] Refactor frameworkToRenderer import and remove deprecated alias --- code/core/src/cli/helpers.ts | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/code/core/src/cli/helpers.ts b/code/core/src/cli/helpers.ts index 9bab59fdd85..a6dcefb89ce 100644 --- a/code/core/src/cli/helpers.ts +++ b/code/core/src/cli/helpers.ts @@ -3,10 +3,10 @@ import { cp, readFile, writeFile } from 'node:fs/promises'; import { join, resolve } from 'node:path'; import { - frameworkToRenderer as CoreFrameworkToRenderer, type JsPackageManager, type PackageJson, type PackageJsonWithDepsAndDevDeps, + frameworkToRenderer, } from 'storybook/internal/common'; import { versions as storybookMonorepoPackages } from 'storybook/internal/common'; import type { SupportedFrameworks, SupportedRenderers } from 'storybook/internal/types'; @@ -142,9 +142,6 @@ type CopyTemplateFilesOptions = { features: string[]; }; -/** @deprecated Please use `frameworkToRenderer` from `storybook/internal/common` instead */ -export const frameworkToRenderer = CoreFrameworkToRenderer; - export const frameworkToDefaultBuilder: Record< SupportedFrameworks, CoreBuilder | CommunityBuilder From 67fb6083817ab6dd9d042cd704376e519147e6e4 Mon Sep 17 00:00:00 2001 From: Valentin Palkovic Date: Tue, 25 Mar 2025 15:37:51 +0100 Subject: [PATCH 05/37] Remove IconButtonSkeleton component and update exports accordingly --- .../src/components/components/bar/button.tsx | 20 ------------------- code/core/src/components/index.ts | 2 +- code/core/src/manager/globals/exports.ts | 1 - 3 files changed, 1 insertion(+), 22 deletions(-) diff --git a/code/core/src/components/components/bar/button.tsx b/code/core/src/components/components/bar/button.tsx index ba8587e8516..4313a98efcd 100644 --- a/code/core/src/components/components/bar/button.tsx +++ b/code/core/src/components/components/bar/button.tsx @@ -132,23 +132,3 @@ export interface IconButtonProps { active?: boolean; disabled?: boolean; } - -const IconPlaceholder = styled.div(({ theme }) => ({ - width: 14, - height: 14, - backgroundColor: theme.appBorderColor, - animation: `${theme.animation.glow} 1.5s ease-in-out infinite`, -})); - -const IconButtonSkeletonWrapper = styled.div({ - marginTop: 6, - padding: 7, - height: 28, -}); - -/** @deprecated This component will be removed in Storybook 9.0 */ -export const IconButtonSkeleton = () => ( - - - -); diff --git a/code/core/src/components/index.ts b/code/core/src/components/index.ts index 5222b7bd638..0510b9d5909 100644 --- a/code/core/src/components/index.ts +++ b/code/core/src/components/index.ts @@ -67,7 +67,7 @@ export { default as ListItem } from './components/tooltip/ListItem'; // Toolbar and subcomponents export { Tabs, TabsState, TabBar, TabWrapper } from './components/tabs/tabs'; export { EmptyTabContent } from './components/tabs/EmptyTabContent'; -export { IconButtonSkeleton, TabButton } from './components/bar/button'; +export { TabButton } from './components/bar/button'; export { Separator, interleaveSeparators } from './components/bar/separator'; export { Bar, FlexBar } from './components/bar/bar'; export { AddonPanel } from './components/addon-panel/addon-panel'; diff --git a/code/core/src/manager/globals/exports.ts b/code/core/src/manager/globals/exports.ts index 7f34241898d..3a0099ad471 100644 --- a/code/core/src/manager/globals/exports.ts +++ b/code/core/src/manager/globals/exports.ts @@ -492,7 +492,6 @@ export default { 'H6', 'HR', 'IconButton', - 'IconButtonSkeleton', 'Icons', 'Img', 'LI', From b681c7d69b71598ffff9e93c594129d55e7f9163 Mon Sep 17 00:00:00 2001 From: Valentin Palkovic Date: Tue, 25 Mar 2025 19:16:29 +0100 Subject: [PATCH 06/37] Don't export deprecated icon component --- code/core/src/components/index.ts | 3 --- code/core/src/toolbar/components/ToolbarMenuListItem.tsx | 2 +- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/code/core/src/components/index.ts b/code/core/src/components/index.ts index 0510b9d5909..119a6a83ca7 100644 --- a/code/core/src/components/index.ts +++ b/code/core/src/components/index.ts @@ -73,9 +73,6 @@ export { Bar, FlexBar } from './components/bar/bar'; export { AddonPanel } from './components/addon-panel/addon-panel'; // Graphics -export type { IconsProps } from './components/icon/icon'; -export { Icons, Symbols } from './components/icon/icon'; -export { icons } from './components/icon/icon'; export { StorybookLogo } from './brand/StorybookLogo'; export { StorybookIcon } from './brand/StorybookIcon'; diff --git a/code/core/src/toolbar/components/ToolbarMenuListItem.tsx b/code/core/src/toolbar/components/ToolbarMenuListItem.tsx index 37ae26d1aeb..3ebb317aba4 100644 --- a/code/core/src/toolbar/components/ToolbarMenuListItem.tsx +++ b/code/core/src/toolbar/components/ToolbarMenuListItem.tsx @@ -1,8 +1,8 @@ import React from 'react'; import type { TooltipLinkListLink } from 'storybook/internal/components'; -import { Icons } from 'storybook/internal/components'; +import { Icons } from '../../components/components/icon/icon'; import type { ToolbarItem } from '../types'; export type ToolbarMenuListItemProps = { From f213b1c754c46260fa1b86bc555bb126ec0aa12f Mon Sep 17 00:00:00 2001 From: Valentin Palkovic Date: Tue, 25 Mar 2025 19:17:26 +0100 Subject: [PATCH 07/37] Remove deprecated _fileName getter from CsfFile class --- code/core/src/csf-tools/CsfFile.ts | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/code/core/src/csf-tools/CsfFile.ts b/code/core/src/csf-tools/CsfFile.ts index 918188239be..19be1416a14 100644 --- a/code/core/src/csf-tools/CsfFile.ts +++ b/code/core/src/csf-tools/CsfFile.ts @@ -278,16 +278,6 @@ export class CsfFile { imports: string[]; - /** @deprecated Use `_options.fileName` instead */ - get _fileName() { - return this._options.fileName; - } - - /** @deprecated Use `_options.makeTitle` instead */ - get _makeTitle() { - return this._options.makeTitle; - } - constructor(ast: t.File, options: CsfOptions, file: BabelFile) { this._ast = ast; this._file = file; From 76b4932c3104769228bb12797956521662396e1e Mon Sep 17 00:00:00 2001 From: Valentin Palkovic Date: Tue, 25 Mar 2025 19:29:47 +0100 Subject: [PATCH 08/37] Refactor StoryIndexGenerator to remove deprecated autodocs option and update tests accordingly --- .../utils/StoryIndexGenerator.test.ts | 201 +++++++++++------- .../core-server/utils/StoryIndexGenerator.ts | 10 +- .../utils/__tests__/index-extraction.test.ts | 107 +--------- .../core-server/utils/stories-json.test.ts | 41 +++- code/core/src/types/modules/core-common.ts | 7 - .../automigrate/fixes/autodocs-tags.test.ts | 76 ------- .../src/automigrate/fixes/autodocs-tags.ts | 95 --------- .../automigrate/fixes/autodocs-true.test.ts | 48 ----- .../src/automigrate/fixes/autodocs-true.ts | 92 -------- .../src/automigrate/fixes/index.ts | 4 - 10 files changed, 173 insertions(+), 508 deletions(-) delete mode 100644 code/lib/cli-storybook/src/automigrate/fixes/autodocs-tags.test.ts delete mode 100644 code/lib/cli-storybook/src/automigrate/fixes/autodocs-tags.ts delete mode 100644 code/lib/cli-storybook/src/automigrate/fixes/autodocs-true.test.ts delete mode 100644 code/lib/cli-storybook/src/automigrate/fixes/autodocs-true.ts diff --git a/code/core/src/core-server/utils/StoryIndexGenerator.test.ts b/code/core/src/core-server/utils/StoryIndexGenerator.test.ts index 7f068143ba0..c08c2906fb9 100644 --- a/code/core/src/core-server/utils/StoryIndexGenerator.test.ts +++ b/code/core/src/core-server/utils/StoryIndexGenerator.test.ts @@ -40,7 +40,7 @@ const options: StoryIndexGeneratorOptions = { configDir: join(__dirname, '__mockdata__'), workingDir: join(__dirname, '__mockdata__'), indexers: [csfIndexer], - docs: { defaultName: 'docs', autodocs: false }, + docs: { defaultName: 'docs' }, }; describe('StoryIndexGenerator', () => { @@ -121,6 +121,19 @@ describe('StoryIndexGenerator', () => { expect(storyIndex).toMatchInlineSnapshot(` { "entries": { + "f--docs": { + "id": "f--docs", + "importPath": "./src/F.story.ts", + "name": "docs", + "storiesImports": [], + "tags": [ + "dev", + "test", + "autodocs", + ], + "title": "F", + "type": "docs", + }, "f--story-one": { "componentPath": undefined, "id": "f--story-one", @@ -154,6 +167,19 @@ describe('StoryIndexGenerator', () => { expect(storyIndex).toMatchInlineSnapshot(` { "entries": { + "stories--docs": { + "id": "stories--docs", + "importPath": "./src/stories.ts", + "name": "docs", + "storiesImports": [], + "tags": [ + "dev", + "test", + "autodocs", + ], + "title": "stories", + "type": "docs", + }, "stories--story-one": { "componentPath": undefined, "id": "stories--story-one", @@ -282,6 +308,19 @@ describe('StoryIndexGenerator', () => { "title": "A", "type": "story", }, + "b--docs": { + "id": "b--docs", + "importPath": "./src/B.stories.ts", + "name": "docs", + "storiesImports": [], + "tags": [ + "dev", + "test", + "autodocs", + ], + "title": "B", + "type": "docs", + }, "b--story-one": { "componentPath": undefined, "id": "b--story-one", @@ -331,6 +370,19 @@ describe('StoryIndexGenerator', () => { "title": "componentPath/package", "type": "story", }, + "d--docs": { + "id": "d--docs", + "importPath": "./src/D.stories.jsx", + "name": "docs", + "storiesImports": [], + "tags": [ + "dev", + "test", + "autodocs", + ], + "title": "D", + "type": "docs", + }, "d--story-one": { "componentPath": undefined, "id": "d--story-one", @@ -431,6 +483,19 @@ describe('StoryIndexGenerator', () => { "title": "first-nested/deeply/Features", "type": "story", }, + "h--docs": { + "id": "h--docs", + "importPath": "./src/H.stories.mjs", + "name": "docs", + "storiesImports": [], + "tags": [ + "dev", + "test", + "autodocs", + ], + "title": "H", + "type": "docs", + }, "h--story-one": { "componentPath": undefined, "id": "h--story-one", @@ -787,37 +852,28 @@ describe('StoryIndexGenerator', () => { await generator.initialize(); expect(Object.keys((await generator.getIndex()).entries)).toMatchInlineSnapshot(` - [ - "a--docs", - "a--story-one", - "b--docs", - "b--story-one", - "example-button--docs", - "example-button--story-one", - "d--docs", - "d--story-one", - "h--docs", - "h--story-one", - "componentpath-extension--docs", - "componentpath-extension--story-one", - "componentpath-noextension--docs", - "componentpath-noextension--story-one", - "componentpath-package--docs", - "componentpath-package--story-one", - "first-nested-deeply-f--docs", - "first-nested-deeply-f--story-one", - "first-nested-deeply-features--docs", - "first-nested-deeply-features--with-play", - "first-nested-deeply-features--with-story-fn", - "first-nested-deeply-features--with-render", - "first-nested-deeply-features--with-test", - "first-nested-deeply-features--with-csf-1", - "nested-button--docs", - "nested-button--story-one", - "second-nested-g--docs", - "second-nested-g--story-one", - ] - `); + [ + "a--story-one", + "b--docs", + "b--story-one", + "example-button--story-one", + "d--docs", + "d--story-one", + "h--docs", + "h--story-one", + "componentpath-extension--story-one", + "componentpath-noextension--story-one", + "componentpath-package--story-one", + "first-nested-deeply-f--story-one", + "first-nested-deeply-features--with-play", + "first-nested-deeply-features--with-story-fn", + "first-nested-deeply-features--with-render", + "first-nested-deeply-features--with-test", + "first-nested-deeply-features--with-csf-1", + "nested-button--story-one", + "second-nested-g--story-one", + ] +`); }); it('generates an entry for every CSF file when projectTags contains autodocs', async () => { @@ -864,21 +920,6 @@ describe('StoryIndexGenerator', () => { `); }); - it('adds the autodocs tag to the autogenerated docs entries when docsOptions.autodocs = true', async () => { - const specifier: NormalizedStoriesSpecifier = normalizeStoriesEntry( - './src/**/*.stories.(ts|js|mjs|jsx)', - options - ); - - const generator = new StoryIndexGenerator([specifier], autodocsTrueOptions); - await generator.initialize(); - - const index = await generator.getIndex(); - expect(index.entries['first-nested-deeply-f--docs'].tags).toEqual( - expect.arrayContaining(['autodocs']) - ); - }); - it('adds the autodocs tag to the autogenerated docs entries when projectTags contains autodocs', async () => { const specifier: NormalizedStoriesSpecifier = normalizeStoriesEntry( './src/**/*.stories.(ts|js|mjs|jsx)', @@ -1095,7 +1136,6 @@ describe('StoryIndexGenerator', () => { "tags": [ "dev", "test", - "autodocs", "component-tag", "story-tag", "attached-mdx", @@ -1111,7 +1151,6 @@ describe('StoryIndexGenerator', () => { "tags": [ "dev", "test", - "autodocs", "component-tag", "story-tag", ], @@ -1572,6 +1611,19 @@ describe('StoryIndexGenerator', () => { "title": "A", "type": "story", }, + "b--docs": { + "id": "b--docs", + "importPath": "./src/B.stories.ts", + "name": "docs", + "storiesImports": [], + "tags": [ + "dev", + "test", + "autodocs", + ], + "title": "B", + "type": "docs", + }, "b--story-one": { "componentPath": undefined, "id": "b--story-one", @@ -1815,30 +1867,33 @@ describe('StoryIndexGenerator', () => { }); expect(Object.keys((await generator.getIndex()).entries)).toMatchInlineSnapshot(` - [ - "docs2-yabbadabbadooo--docs", - "d--story-one", - "b--story-one", - "nested-button--story-one", - "a--metaof", - "a--second-docs", - "a--story-one", - "second-nested-g--story-one", - "componentreference--docs", - "notitle--docs", - "example-button--story-one", - "h--story-one", - "componentpath-extension--story-one", - "componentpath-noextension--story-one", - "componentpath-package--story-one", - "first-nested-deeply-f--story-one", - "first-nested-deeply-features--with-play", - "first-nested-deeply-features--with-story-fn", - "first-nested-deeply-features--with-render", - "first-nested-deeply-features--with-test", - "first-nested-deeply-features--with-csf-1", - ] - `); + [ + "docs2-yabbadabbadooo--docs", + "d--docs", + "d--story-one", + "b--docs", + "b--story-one", + "nested-button--story-one", + "a--metaof", + "a--second-docs", + "a--story-one", + "second-nested-g--story-one", + "componentreference--docs", + "notitle--docs", + "example-button--story-one", + "h--docs", + "h--story-one", + "componentpath-extension--story-one", + "componentpath-noextension--story-one", + "componentpath-package--story-one", + "first-nested-deeply-f--story-one", + "first-nested-deeply-features--with-play", + "first-nested-deeply-features--with-story-fn", + "first-nested-deeply-features--with-render", + "first-nested-deeply-features--with-test", + "first-nested-deeply-features--with-csf-1", + ] +`); }); }); diff --git a/code/core/src/core-server/utils/StoryIndexGenerator.ts b/code/core/src/core-server/utils/StoryIndexGenerator.ts index 58000077e4c..f6bda142243 100644 --- a/code/core/src/core-server/utils/StoryIndexGenerator.ts +++ b/code/core/src/core-server/utils/StoryIndexGenerator.ts @@ -400,7 +400,7 @@ export class StoryIndexGenerator { // a) autodocs is globally enabled // b) we have autodocs enabled for this file const hasAutodocsTag = entries.some((entry) => entry.tags.includes(AUTODOCS_TAG)); - const createDocEntry = hasAutodocsTag && !!this.options.docs.autodocs; + const createDocEntry = hasAutodocsTag; if (createDocEntry && this.options.build?.test?.disableAutoDocs !== true) { const name = this.options.docs.defaultName ?? 'Docs'; @@ -592,10 +592,7 @@ export class StoryIndexGenerator { } // If you link a file to a tagged CSF file, you have probably made a mistake - if ( - worseEntry.tags?.includes(AUTODOCS_TAG) && - !(this.options.docs.autodocs === true || projectTags?.includes(AUTODOCS_TAG)) - ) { + if (worseEntry.tags?.includes(AUTODOCS_TAG) && !projectTags?.includes(AUTODOCS_TAG)) { throw new IndexingError( `You created a component docs page for '${worseEntry.title}', but also tagged the CSF file with '${AUTODOCS_TAG}'. This is probably a mistake.`, [betterEntry.importPath, worseEntry.importPath] @@ -768,7 +765,6 @@ export class StoryIndexGenerator { getProjectTags(previewCode?: string) { let projectTags = [] as Tag[]; const defaultTags = ['dev', 'test']; - const extraTags = this.options.docs.autodocs === true ? [AUTODOCS_TAG] : []; if (previewCode) { try { const projectAnnotations = loadConfig(previewCode).parse(); @@ -789,7 +785,7 @@ export class StoryIndexGenerator { `); } } - return [...defaultTags, ...projectTags, ...extraTags]; + return [...defaultTags, ...projectTags]; } // Get the story file names in "imported order" diff --git a/code/core/src/core-server/utils/__tests__/index-extraction.test.ts b/code/core/src/core-server/utils/__tests__/index-extraction.test.ts index a6c9dd01ba4..41cfdf116fc 100644 --- a/code/core/src/core-server/utils/__tests__/index-extraction.test.ts +++ b/code/core/src/core-server/utils/__tests__/index-extraction.test.ts @@ -14,7 +14,7 @@ const options: StoryIndexGeneratorOptions = { configDir: join(__dirname, '..', '__mockdata__'), workingDir: join(__dirname, '..', '__mockdata__'), indexers: [], - docs: { defaultName: 'docs', autodocs: false }, + docs: { defaultName: 'docs' }, }; describe('story extraction', () => { @@ -392,57 +392,6 @@ describe('story extraction', () => { }); }); describe('docs entries from story extraction', () => { - it('adds docs entry when autodocs is globally enabled', async () => { - const relativePath = './src/A.stories.js'; - const absolutePath = join(options.workingDir, relativePath); - const specifier: NormalizedStoriesSpecifier = normalizeStoriesEntry(relativePath, options); - - const generator = new StoryIndexGenerator([specifier], { - ...options, - docs: { defaultName: 'docs', autodocs: true }, - indexers: [ - { - test: /\.stories\.(m?js|ts)x?$/, - createIndex: async (fileName) => [ - { - exportName: 'StoryOne', - __id: 'a--story-one', - name: 'Story One', - title: 'A', - tags: ['story-tag-from-indexer'], - importPath: fileName, - type: 'story', - }, - ], - }, - ], - }); - const result = await generator.extractStories(specifier, absolutePath); - - expect(result).toMatchInlineSnapshot(` - { - "dependents": [], - "entries": [ - { - "componentPath": undefined, - "extra": { - "metaId": undefined, - "stats": {}, - }, - "id": "a--story-one", - "importPath": "./src/A.stories.js", - "name": "Story One", - "tags": [ - "story-tag-from-indexer", - ], - "title": "A", - "type": "story", - }, - ], - "type": "stories", - } - `); - }); it(`adds docs entry when autodocs is "tag" and an entry has the "${AUTODOCS_TAG}" tag`, async () => { const relativePath = './src/A.stories.js'; const absolutePath = join(options.workingDir, relativePath); @@ -450,7 +399,7 @@ describe('docs entries from story extraction', () => { const generator = new StoryIndexGenerator([specifier], { ...options, - docs: { defaultName: 'docs', autodocs: 'tag' }, + docs: { defaultName: 'docs' }, indexers: [ { test: /\.stories\.(m?js|ts)x?$/, @@ -507,56 +456,4 @@ describe('docs entries from story extraction', () => { } `); }); - it(`DOES NOT adds docs entry when autodocs is false and an entry has the "${AUTODOCS_TAG}" tag`, async () => { - const relativePath = './src/A.stories.js'; - const absolutePath = join(options.workingDir, relativePath); - const specifier: NormalizedStoriesSpecifier = normalizeStoriesEntry(relativePath, options); - - const generator = new StoryIndexGenerator([specifier], { - ...options, - docs: { defaultName: 'docs', autodocs: false }, - indexers: [ - { - test: /\.stories\.(m?js|ts)x?$/, - createIndex: async (fileName) => [ - { - exportName: 'StoryOne', - __id: 'a--story-one', - name: 'Story One', - title: 'A', - tags: [AUTODOCS_TAG, 'story-tag-from-indexer'], - importPath: fileName, - type: 'story', - }, - ], - }, - ], - }); - const result = await generator.extractStories(specifier, absolutePath); - - expect(result).toMatchInlineSnapshot(` - { - "dependents": [], - "entries": [ - { - "componentPath": undefined, - "extra": { - "metaId": undefined, - "stats": {}, - }, - "id": "a--story-one", - "importPath": "./src/A.stories.js", - "name": "Story One", - "tags": [ - "autodocs", - "story-tag-from-indexer", - ], - "title": "A", - "type": "story", - }, - ], - "type": "stories", - } - `); - }); }); diff --git a/code/core/src/core-server/utils/stories-json.test.ts b/code/core/src/core-server/utils/stories-json.test.ts index d065a481a47..a7c7d1c3546 100644 --- a/code/core/src/core-server/utils/stories-json.test.ts +++ b/code/core/src/core-server/utils/stories-json.test.ts @@ -47,7 +47,7 @@ const getInitializedStoryIndexGenerator = async ( indexers: [csfIndexer], configDir: workingDir, workingDir, - docs: { defaultName: 'docs', autodocs: false }, + docs: { defaultName: 'docs' }, ...overrides, }; const generator = new StoryIndexGenerator(inputNormalizedStories, options); @@ -155,6 +155,19 @@ describe('useStoriesJson', () => { "title": "A", "type": "story", }, + "b--docs": { + "id": "b--docs", + "importPath": "./src/B.stories.ts", + "name": "docs", + "storiesImports": [], + "tags": [ + "dev", + "test", + "autodocs", + ], + "title": "B", + "type": "docs", + }, "b--story-one": { "id": "b--story-one", "importPath": "./src/B.stories.ts", @@ -203,6 +216,19 @@ describe('useStoriesJson', () => { "title": "componentPath/package", "type": "story", }, + "d--docs": { + "id": "d--docs", + "importPath": "./src/D.stories.jsx", + "name": "docs", + "storiesImports": [], + "tags": [ + "dev", + "test", + "autodocs", + ], + "title": "D", + "type": "docs", + }, "d--story-one": { "id": "d--story-one", "importPath": "./src/D.stories.jsx", @@ -334,6 +360,19 @@ describe('useStoriesJson', () => { "title": "first-nested/deeply/Features", "type": "story", }, + "h--docs": { + "id": "h--docs", + "importPath": "./src/H.stories.mjs", + "name": "docs", + "storiesImports": [], + "tags": [ + "dev", + "test", + "autodocs", + ], + "title": "H", + "type": "docs", + }, "h--story-one": { "id": "h--story-one", "importPath": "./src/H.stories.mjs", diff --git a/code/core/src/types/modules/core-common.ts b/code/core/src/types/modules/core-common.ts index 3627539992a..7248d69d99f 100644 --- a/code/core/src/types/modules/core-common.ts +++ b/code/core/src/types/modules/core-common.ts @@ -297,13 +297,6 @@ type CoreCommon_StorybookRefs = Record< export type DocsOptions = { /** What should we call the generated docs entries? */ defaultName?: string; - /** - * Should we generate a docs entry per CSF file? Set to 'tag' (the default) to generate an entry - * for every CSF file with the 'autodocs' tag. - * - * @deprecated Use `tags: ['autodocs']` in `.storybook/preview.js` instead - */ - autodocs?: boolean | 'tag'; /** Only show doc entries in the side bar (usually set with the `--docs` CLI flag) */ docsMode?: boolean; }; diff --git a/code/lib/cli-storybook/src/automigrate/fixes/autodocs-tags.test.ts b/code/lib/cli-storybook/src/automigrate/fixes/autodocs-tags.test.ts deleted file mode 100644 index 9f5cc2f9b23..00000000000 --- a/code/lib/cli-storybook/src/automigrate/fixes/autodocs-tags.test.ts +++ /dev/null @@ -1,76 +0,0 @@ -import { describe, expect, it } from 'vitest'; - -import type { StorybookConfig } from 'storybook/internal/types'; - -import { autodocsTags } from './autodocs-tags'; - -const check = async ({ - main: mainConfig, - storybookVersion = '7.0.0', - previewConfigPath, -}: { - main: Partial & Record; - storybookVersion?: string; - previewConfigPath?: string; -}) => { - return autodocsTags.check({ - packageManager: {} as any, - configDir: '', - mainConfig: mainConfig as any, - storybookVersion, - previewConfigPath, - }); -}; - -it('with no docs setting', async () => { - await expect( - check({ - main: {}, - }) - ).resolves.toBeFalsy(); -}); - -describe('docs.autodocs = true', () => { - it('errors with no preview.js', async () => { - await expect( - check({ - main: { - docs: { autodocs: true }, - }, - }) - ).rejects.toThrowError(); - }); - - it('continues with preview.js', async () => { - await expect( - check({ - main: { - docs: { autodocs: true }, - }, - previewConfigPath: '.storybook/preview.js', - }) - ).resolves.toBeTruthy(); - }); -}); - -describe('docs.autodocs != true', () => { - it('docs.autodocs = false', async () => { - await expect( - check({ - main: { - docs: { autodocs: false }, - }, - }) - ).resolves.toBeTruthy(); - }); - - it('docs.autodocs = "tag"', async () => { - await expect( - check({ - main: { - docs: { autodocs: 'tag' }, - }, - }) - ).resolves.toBeTruthy(); - }); -}); diff --git a/code/lib/cli-storybook/src/automigrate/fixes/autodocs-tags.ts b/code/lib/cli-storybook/src/automigrate/fixes/autodocs-tags.ts deleted file mode 100644 index 30d5c9a5ed8..00000000000 --- a/code/lib/cli-storybook/src/automigrate/fixes/autodocs-tags.ts +++ /dev/null @@ -1,95 +0,0 @@ -import { readConfig, writeConfig } from 'storybook/internal/csf-tools'; -import type { DocsOptions } from 'storybook/internal/types'; - -import picocolors from 'picocolors'; -import { dedent } from 'ts-dedent'; - -import { updateMainConfig } from '../helpers/mainConfigFile'; -import type { Fix } from '../types'; - -const logger = console; - -const MIGRATION = - 'https://github.com/storybookjs/storybook/blob/next/MIGRATION.md#mainjs-docsautodocs-is-deprecated'; - -interface Options { - autodocs: DocsOptions['autodocs']; - mainConfigPath?: string; - previewConfigPath?: string; -} - -export const autodocsTags: Fix = { - id: 'autodocs-tags', - versionRange: ['*.*.*', '>=8.0.*'], - async check({ mainConfig, mainConfigPath, previewConfigPath }) { - const autodocs = mainConfig?.docs?.autodocs; - - if (autodocs === undefined) { - return null; - } - - if (autodocs === true && !previewConfigPath) { - throw Error(dedent` - ❌ Failed to remove the deprecated ${picocolors.cyan( - 'docs.autodocs' - )} setting from ${picocolors.cyan(mainConfigPath)}. - - There is no preview config file in which to add the ${picocolors.cyan('autodocs')} tag. - - Please perform the migration by hand: ${picocolors.yellow(MIGRATION)} - `); - return null; - } - - return { autodocs, mainConfigPath, previewConfigPath }; - }, - - prompt({ autodocs, mainConfigPath, previewConfigPath }) { - let falseMessage = '', - trueMessage = ''; - - if (autodocs === false) { - falseMessage = dedent` - - - There is no ${picocolors.cyan('docs.autodocs = false')} equivalent. - You'll need to check your stories to ensure none are tagged with ${picocolors.cyan( - 'autodocs' - )}. - `; - } else if (autodocs === true) { - trueMessage = ` and update ${picocolors.cyan(previewConfigPath)}`; - } - - return dedent` - The ${picocolors.cyan('docs.autodocs')} setting in ${picocolors.cyan( - mainConfigPath - )} is deprecated.${falseMessage} - - Learn more: ${picocolors.yellow(MIGRATION)} - - Remove ${picocolors.cyan('docs.autodocs')}${trueMessage}? - `; - }, - - async run({ dryRun, mainConfigPath, result }) { - if (!dryRun) { - if (result.autodocs === true) { - logger.info(`✅ Adding "autodocs" tag to ${result.previewConfigPath}`); - const previewConfig = await readConfig(result.previewConfigPath!); - const tags = previewConfig.getFieldNode(['tags']); - if (tags) { - previewConfig.appendValueToArray(['tags'], 'autodocs'); - } else { - previewConfig.setFieldValue(['tags'], ['autodocs']); - } - await writeConfig(previewConfig); - } - - await updateMainConfig({ mainConfigPath, dryRun: !!dryRun }, async (main) => { - logger.info(`✅ Removing "docs.autodocs" from ${mainConfigPath}`); - main.removeField(['docs', 'autodocs']); - }); - } - }, -}; diff --git a/code/lib/cli-storybook/src/automigrate/fixes/autodocs-true.test.ts b/code/lib/cli-storybook/src/automigrate/fixes/autodocs-true.test.ts deleted file mode 100644 index a62591bd881..00000000000 --- a/code/lib/cli-storybook/src/automigrate/fixes/autodocs-true.test.ts +++ /dev/null @@ -1,48 +0,0 @@ -import { afterEach, describe, expect, it, vi } from 'vitest'; - -import type { PackageJson, StorybookConfigRaw } from 'storybook/internal/types'; - -import { makePackageManager } from '../helpers/testing-helpers'; -import { autodocsTrue } from './autodocs-true'; - -const checkAutodocs = async ({ - packageJson = {}, - main: mainConfig, -}: { - packageJson?: PackageJson; - main: Partial & Record; -}) => { - return autodocsTrue.check({ - packageManager: makePackageManager(packageJson), - mainConfig: mainConfig as StorybookConfigRaw, - storybookVersion: '7.0.0', - }); -}; - -describe('autodocs-true fix', () => { - afterEach(() => { - vi.restoreAllMocks(); - }); - - it('should skip when docs.autodocs is already defined', async () => { - await expect(checkAutodocs({ main: { docs: { autodocs: 'tag' } } })).resolves.toBeFalsy(); - }); - - it('should throw when docs.docsPage contains invalid value', async () => { - const main = { docs: { docsPage: 123 } } as any; - await expect(checkAutodocs({ main })).rejects.toThrow(); - }); - - it('should prompt when using docs.docsPage legacy property', async () => { - const main = { docs: { docsPage: true } } as any; - await expect(checkAutodocs({ main })).resolves.toEqual({ - value: 'tag', - }); - }); - - it('should prompt when not using docs.autodocs', async () => { - await expect(checkAutodocs({ main: {} })).resolves.toEqual({ - value: true, - }); - }); -}); diff --git a/code/lib/cli-storybook/src/automigrate/fixes/autodocs-true.ts b/code/lib/cli-storybook/src/automigrate/fixes/autodocs-true.ts deleted file mode 100644 index 9ed1aa6b06e..00000000000 --- a/code/lib/cli-storybook/src/automigrate/fixes/autodocs-true.ts +++ /dev/null @@ -1,92 +0,0 @@ -import picocolors from 'picocolors'; -import { dedent } from 'ts-dedent'; - -import { updateMainConfig } from '../helpers/mainConfigFile'; -import type { Fix } from '../types'; - -const logger = console; - -interface AutodocsTrueFrameworkRunOptions { - value?: boolean | 'tag'; -} - -/** Set the `docs.autodocs` option to true if it isn't already set */ -export const autodocsTrue: Fix = { - id: 'autodocsTrue', - - versionRange: ['<7', '>=7'], - - async check({ mainConfig }) { - const { docs } = mainConfig; - - const docsPageToAutodocsMapping = { - true: 'tag' as const, - automatic: true, - false: false, - }; - - // @ts-expect-error docsPage does not exist anymore but we need to account for legacy code - if (docs?.docsPage) { - // @ts-expect-error same as above - const oldValue = docs?.docsPage.toString(); - if (!(oldValue in docsPageToAutodocsMapping)) { - throw new Error(`Unexpected value for docs.docsPage: ${oldValue}`); - } - - return { - value: docsPageToAutodocsMapping[oldValue as keyof typeof docsPageToAutodocsMapping], - }; - } - - return docs?.autodocs === undefined ? { value: true } : null; - }, - - prompt({ value }) { - const autodocsFormatted = picocolors.cyan( - `docs: { autodocs: ${JSON.stringify(value ?? true)} }` - ); - const tagWarning = dedent` - NOTE: if you're upgrading from an older 7.0-beta using the 'docsPage' tag, - please update your story files to use the 'autodocs' tag instead. - `; - - if (value) { - return dedent` - We've changed the configuration of autodocs (previous docsPage), so now the value: - - docs.autodocs: true -- means automatically create docs for every CSF file - - docs.autodocs: 'tag' -- means only create autodocs for CSF files with the 'autodocs' tag - - docs.autodocs: false -- means never create autodocs - - Based on your prior configuration, we can set the \`docs.autodocs\` to keep your old behaviour: - - ${autodocsFormatted} - ${value === 'tag' ? tagWarning : ''} - More info: ${picocolors.yellow( - 'https://github.com/storybookjs/storybook/blob/next/MIGRATION.md#autodocs-changes' - )} - `; - } - - return dedent` - We've detected that your main.js configuration file has not configured autodocs. In 6.x we - we defaulted to having a autodocs for every story, in 7.x you need to opt in per-component. - However, we can set the \`docs.autodocs\` to true to approximate the old behaviour: - - ${autodocsFormatted} - - More info: ${picocolors.yellow( - 'https://github.com/storybookjs/storybook/blob/next/MIGRATION.md#autodocs-changes' - )} - `; - }, - - async run({ result: { value }, dryRun, mainConfigPath }) { - logger.info(`✅ Setting 'docs.autodocs' to true in main.js`); - if (!dryRun) { - await updateMainConfig({ mainConfigPath, dryRun: !!dryRun }, async (main) => { - main.removeField(['docs', 'docsPage']); - main.setFieldValue(['docs', 'autodocs'], value ?? true); - }); - } - }, -}; diff --git a/code/lib/cli-storybook/src/automigrate/fixes/index.ts b/code/lib/cli-storybook/src/automigrate/fixes/index.ts index 717fbbf33fc..a1593ceb8ef 100644 --- a/code/lib/cli-storybook/src/automigrate/fixes/index.ts +++ b/code/lib/cli-storybook/src/automigrate/fixes/index.ts @@ -7,8 +7,6 @@ import { addonPostCSS } from './addon-postcss'; import { addonsAPI } from './addons-api'; import { angularBuilders } from './angular-builders'; import { angularBuildersMultiproject } from './angular-builders-multiproject'; -import { autodocsTags } from './autodocs-tags'; -import { autodocsTrue } from './autodocs-true'; import { builderVite } from './builder-vite'; import { consolidatedImports } from './consolidated-imports'; import { cra5 } from './cra5'; @@ -55,7 +53,6 @@ export const allFixes: Fix[] = [ removedGlobalClientAPIs, mdxgfm, mdxToCSF, - autodocsTrue, angularBuildersMultiproject, angularBuilders, wrapRequire, @@ -67,7 +64,6 @@ export const allFixes: Fix[] = [ mdx1to3, upgradeStorybookRelatedDependencies, vta, - autodocsTags, initialGlobals, addonA11yAddonTest, consolidatedImports, From 5737389f098ea57c337a546f2cc11fcc2ed81f0b Mon Sep 17 00:00:00 2001 From: Valentin Palkovic Date: Wed, 26 Mar 2025 08:24:26 +0100 Subject: [PATCH 09/37] Remove deprecated TESTING_MODULE_RUN_ALL_REQUEST from core-events and related usage in experimental_testmodule --- code/core/src/core-events/index.ts | 3 --- code/core/src/manager-api/modules/experimental_testmodule.ts | 4 ---- 2 files changed, 7 deletions(-) diff --git a/code/core/src/core-events/index.ts b/code/core/src/core-events/index.ts index e1f5ed4e097..faad4b6ae09 100644 --- a/code/core/src/core-events/index.ts +++ b/code/core/src/core-events/index.ts @@ -89,8 +89,6 @@ enum events { TESTING_MODULE_CRASH_REPORT = 'testingModuleCrashReport', TESTING_MODULE_PROGRESS_REPORT = 'testingModuleProgressReport', TESTING_MODULE_RUN_REQUEST = 'testingModuleRunRequest', - /** @deprecated Use TESTING_MODULE_RUN_REQUEST instead */ - TESTING_MODULE_RUN_ALL_REQUEST = 'testingModuleRunAllRequest', TESTING_MODULE_CANCEL_TEST_RUN_REQUEST = 'testingModuleCancelTestRunRequest', TESTING_MODULE_CANCEL_TEST_RUN_RESPONSE = 'testingModuleCancelTestRunResponse', } @@ -160,7 +158,6 @@ export const { TESTING_MODULE_CRASH_REPORT, TESTING_MODULE_PROGRESS_REPORT, TESTING_MODULE_RUN_REQUEST, - TESTING_MODULE_RUN_ALL_REQUEST, TESTING_MODULE_CANCEL_TEST_RUN_REQUEST, TESTING_MODULE_CANCEL_TEST_RUN_RESPONSE, } = events; diff --git a/code/core/src/manager-api/modules/experimental_testmodule.ts b/code/core/src/manager-api/modules/experimental_testmodule.ts index a300ea99747..6d3bc9df953 100644 --- a/code/core/src/manager-api/modules/experimental_testmodule.ts +++ b/code/core/src/manager-api/modules/experimental_testmodule.ts @@ -1,6 +1,5 @@ import { TESTING_MODULE_CANCEL_TEST_RUN_REQUEST, - TESTING_MODULE_RUN_ALL_REQUEST, TESTING_MODULE_RUN_REQUEST, type TestProviderId, type TestProviderState, @@ -98,9 +97,6 @@ export const init: ModuleFn = ({ store, fullAPI }) => { fullAPI.emit(TESTING_MODULE_RUN_REQUEST, payload); - // For backwards compatibility: - fullAPI.emit(TESTING_MODULE_RUN_ALL_REQUEST, { providerId: id }); - return () => api.cancelTestProvider(id); } From 8a53206cce1b35f1506638da97e835ee582d1466 Mon Sep 17 00:00:00 2001 From: Valentin Palkovic Date: Wed, 26 Mar 2025 08:26:52 +0100 Subject: [PATCH 10/37] Remove DeprecatedState interface and related deprecated fields from useStorybookState function --- code/core/src/manager-api/root.tsx | 28 +--------------------------- 1 file changed, 1 insertion(+), 27 deletions(-) diff --git a/code/core/src/manager-api/root.tsx b/code/core/src/manager-api/root.tsx index fd80fad04f5..f822712d2e0 100644 --- a/code/core/src/manager-api/root.tsx +++ b/code/core/src/manager-api/root.tsx @@ -88,7 +88,6 @@ export type State = layout.SubState & whatsnew.SubState & RouterData & API_OptionsData & - DeprecatedState & Other; export type API = addons.SubAPI & @@ -107,15 +106,6 @@ export type API = addons.SubAPI & whatsnew.SubAPI & Other; -interface DeprecatedState { - /** @deprecated Use index */ - storiesHash: API_IndexHash; - /** @deprecated Use previewInitialized */ - storiesConfigured: boolean; - /** @deprecated Use indexError */ - storiesFailed?: Error; -} - interface Other { [key: string]: any; } @@ -299,23 +289,7 @@ function ManagerConsumer

({ export function useStorybookState(): State { const { state } = useContext(ManagerContext); - return { - ...state, - - // deprecated fields for back-compat - get storiesHash() { - deprecate('state.storiesHash is deprecated, please use state.index'); - return this.index || {}; - }, - get storiesConfigured() { - deprecate('state.storiesConfigured is deprecated, please use state.previewInitialized'); - return this.previewInitialized; - }, - get storiesFailed() { - deprecate('state.storiesFailed is deprecated, please use state.indexError'); - return this.indexError; - }, - }; + return state; } export function useStorybookApi(): API { const { api } = useContext(ManagerContext); From 89f03b1909c99f6c139c8acc4ab1f8b253bac08c Mon Sep 17 00:00:00 2001 From: Valentin Palkovic Date: Wed, 26 Mar 2025 08:33:25 +0100 Subject: [PATCH 11/37] Remove deprecated raw() and fromId() methods from StoryStore class --- .../modules/store/StoryStore.test.ts | 177 ------------------ .../preview-api/modules/store/StoryStore.ts | 57 +----- 2 files changed, 1 insertion(+), 233 deletions(-) diff --git a/code/core/src/preview-api/modules/store/StoryStore.test.ts b/code/core/src/preview-api/modules/store/StoryStore.test.ts index 218a6ce6324..c7409d51b1c 100644 --- a/code/core/src/preview-api/modules/store/StoryStore.test.ts +++ b/code/core/src/preview-api/modules/store/StoryStore.test.ts @@ -653,183 +653,6 @@ describe('StoryStore', () => { }); }); - describe('raw', () => { - it('produces an array of stories', async () => { - const store = new StoryStore(storyIndex, importFn, projectAnnotations); - await store.cacheAllCSFFiles(); - - expect(store.raw()).toMatchInlineSnapshot(` - [ - { - "applyAfterEach": [Function], - "applyBeforeEach": [Function], - "applyLoaders": [Function], - "argTypes": { - "a": { - "name": "a", - "type": { - "name": "string", - }, - }, - "foo": { - "name": "foo", - "type": { - "name": "string", - }, - }, - }, - "component": undefined, - "componentId": "component-one", - "id": "component-one--a", - "initialArgs": { - "foo": "a", - }, - "kind": "Component One", - "moduleExport": { - "args": { - "foo": "a", - }, - }, - "mount": [Function], - "name": "A", - "originalStoryFn": [MockFunction spy], - "parameters": { - "__isArgsStory": false, - "fileName": "./src/ComponentOne.stories.js", - "throwPlayFunctionExceptions": false, - }, - "playFunction": undefined, - "renderToCanvas": undefined, - "runStep": [Function], - "story": "A", - "storyFn": [Function], - "storyGlobals": {}, - "subcomponents": undefined, - "tags": [ - "dev", - "test", - ], - "testingLibraryRender": undefined, - "title": "Component One", - "unboundStoryFn": [Function], - "undecoratedStoryFn": [Function], - "usesMount": false, - }, - { - "applyAfterEach": [Function], - "applyBeforeEach": [Function], - "applyLoaders": [Function], - "argTypes": { - "a": { - "name": "a", - "type": { - "name": "string", - }, - }, - "foo": { - "name": "foo", - "type": { - "name": "string", - }, - }, - }, - "component": undefined, - "componentId": "component-one", - "id": "component-one--b", - "initialArgs": { - "foo": "b", - }, - "kind": "Component One", - "moduleExport": { - "args": { - "foo": "b", - }, - }, - "mount": [Function], - "name": "B", - "originalStoryFn": [MockFunction spy], - "parameters": { - "__isArgsStory": false, - "fileName": "./src/ComponentOne.stories.js", - "throwPlayFunctionExceptions": false, - }, - "playFunction": undefined, - "renderToCanvas": undefined, - "runStep": [Function], - "story": "B", - "storyFn": [Function], - "storyGlobals": {}, - "subcomponents": undefined, - "tags": [ - "dev", - "test", - ], - "testingLibraryRender": undefined, - "title": "Component One", - "unboundStoryFn": [Function], - "undecoratedStoryFn": [Function], - "usesMount": false, - }, - { - "applyAfterEach": [Function], - "applyBeforeEach": [Function], - "applyLoaders": [Function], - "argTypes": { - "a": { - "name": "a", - "type": { - "name": "string", - }, - }, - "foo": { - "name": "foo", - "type": { - "name": "string", - }, - }, - }, - "component": undefined, - "componentId": "component-two", - "id": "component-two--c", - "initialArgs": { - "foo": "c", - }, - "kind": "Component Two", - "moduleExport": { - "args": { - "foo": "c", - }, - }, - "mount": [Function], - "name": "C", - "originalStoryFn": [MockFunction spy], - "parameters": { - "__isArgsStory": false, - "fileName": "./src/ComponentTwo.stories.js", - "throwPlayFunctionExceptions": false, - }, - "playFunction": undefined, - "renderToCanvas": undefined, - "runStep": [Function], - "story": "C", - "storyFn": [Function], - "storyGlobals": {}, - "subcomponents": undefined, - "tags": [ - "dev", - "test", - ], - "testingLibraryRender": undefined, - "title": "Component Two", - "unboundStoryFn": [Function], - "undecoratedStoryFn": [Function], - "usesMount": false, - }, - ] -`); - }); - }); - describe('getSetStoriesPayload', () => { it('maps stories list to payload correctly', async () => { const store = new StoryStore(storyIndex, importFn, projectAnnotations); diff --git a/code/core/src/preview-api/modules/store/StoryStore.ts b/code/core/src/preview-api/modules/store/StoryStore.ts index 139ec576071..2cd9e4c732e 100644 --- a/code/core/src/preview-api/modules/store/StoryStore.ts +++ b/code/core/src/preview-api/modules/store/StoryStore.ts @@ -1,11 +1,9 @@ -import { deprecate } from 'storybook/internal/client-logger'; -import type { Canvas, CleanupCallback } from 'storybook/internal/csf'; +import type { CleanupCallback } from 'storybook/internal/csf'; import { CalledExtractOnStoreError, MissingStoryFromCsfFileError, } from 'storybook/internal/preview-errors'; import type { - BoundStory, CSFFile, ComponentTitle, IndexEntry, @@ -18,7 +16,6 @@ import type { PreparedStory, ProjectAnnotations, Renderer, - StoryContext, StoryContextForEnhancers, StoryId, StoryIndex, @@ -28,7 +25,6 @@ import type { import { mapValues, omitBy, pick } from 'es-toolkit'; import memoize from 'memoizerific'; -import type { UserEventObject } from 'storybook/test'; import { HooksContext } from '../addons'; import { ArgsStore } from './ArgsStore'; @@ -386,55 +382,4 @@ export class StoryStore { stories, }; }; - - raw(): BoundStory[] { - deprecate( - 'StoryStore.raw() is deprecated and will be removed in 9.0, please use extract() instead' - ); - return Object.values(this.extract()) - .map(({ id }: { id: StoryId }) => this.fromId(id)) - .filter(Boolean) as BoundStory[]; - } - - fromId(storyId: StoryId): BoundStory | null { - deprecate( - 'StoryStore.fromId() is deprecated and will be removed in 9.0, please use loadStory() instead' - ); - - // Deprecated so won't make a proper error for this - - // Deprecated so won't make a proper error for this - if (!this.cachedCSFFiles) { - // eslint-disable-next-line local-rules/no-uncategorized-errors - throw new Error('Cannot call fromId/raw() unless you call cacheAllCSFFiles() first.'); - } - - let importPath; - try { - ({ importPath } = this.storyIndex.storyIdToEntry(storyId)); - } catch (err) { - return null; - } - const csfFile = this.cachedCSFFiles[importPath]; - const story = this.storyFromCSFFile({ storyId, csfFile }); - return { - ...story, - storyFn: (update) => { - const context = { - ...this.getStoryContext(story), - abortSignal: new AbortController().signal, - canvasElement: null!, - loaded: {}, - step: (label, play) => story.runStep(label, play, context), - context: null!, - mount: null!, - canvas: {} as Canvas, - userEvent: {} as UserEventObject, - viewMode: 'story', - } as StoryContext; - - return story.unboundStoryFn({ ...context, ...update }); - }, - }; - } } From 7ffadfed3d9f43234c8127ff6101622782e0c7be Mon Sep 17 00:00:00 2001 From: Valentin Palkovic Date: Wed, 26 Mar 2025 08:34:31 +0100 Subject: [PATCH 12/37] Remove deprecated getSetStoriesPayload and getStoriesJsonData methods from StoryStore class --- .../modules/store/StoryStore.test.ts | 217 ------------------ .../preview-api/modules/store/StoryStore.ts | 52 ----- 2 files changed, 269 deletions(-) diff --git a/code/core/src/preview-api/modules/store/StoryStore.test.ts b/code/core/src/preview-api/modules/store/StoryStore.test.ts index c7409d51b1c..c25c419155c 100644 --- a/code/core/src/preview-api/modules/store/StoryStore.test.ts +++ b/code/core/src/preview-api/modules/store/StoryStore.test.ts @@ -652,221 +652,4 @@ describe('StoryStore', () => { ]); }); }); - - describe('getSetStoriesPayload', () => { - it('maps stories list to payload correctly', async () => { - const store = new StoryStore(storyIndex, importFn, projectAnnotations); - await store.cacheAllCSFFiles(); - - expect(store.getSetStoriesPayload()).toMatchInlineSnapshot(` - { - "globalParameters": {}, - "globals": { - "a": "b", - }, - "kindParameters": { - "Component One": {}, - "Component Two": {}, - }, - "stories": { - "component-one--a": { - "argTypes": { - "a": { - "name": "a", - "type": { - "name": "string", - }, - }, - "foo": { - "name": "foo", - "type": { - "name": "string", - }, - }, - }, - "args": { - "foo": "a", - }, - "component": undefined, - "componentId": "component-one", - "globals": { - "a": "b", - }, - "id": "component-one--a", - "initialArgs": { - "foo": "a", - }, - "kind": "Component One", - "name": "A", - "parameters": { - "__isArgsStory": false, - "fileName": "./src/ComponentOne.stories.js", - "throwPlayFunctionExceptions": false, - }, - "playFunction": undefined, - "renderToCanvas": undefined, - "story": "A", - "storyGlobals": {}, - "subcomponents": undefined, - "tags": [ - "dev", - "test", - ], - "testingLibraryRender": undefined, - "title": "Component One", - "usesMount": false, - }, - "component-one--b": { - "argTypes": { - "a": { - "name": "a", - "type": { - "name": "string", - }, - }, - "foo": { - "name": "foo", - "type": { - "name": "string", - }, - }, - }, - "args": { - "foo": "b", - }, - "component": undefined, - "componentId": "component-one", - "globals": { - "a": "b", - }, - "id": "component-one--b", - "initialArgs": { - "foo": "b", - }, - "kind": "Component One", - "name": "B", - "parameters": { - "__isArgsStory": false, - "fileName": "./src/ComponentOne.stories.js", - "throwPlayFunctionExceptions": false, - }, - "playFunction": undefined, - "renderToCanvas": undefined, - "story": "B", - "storyGlobals": {}, - "subcomponents": undefined, - "tags": [ - "dev", - "test", - ], - "testingLibraryRender": undefined, - "title": "Component One", - "usesMount": false, - }, - "component-two--c": { - "argTypes": { - "a": { - "name": "a", - "type": { - "name": "string", - }, - }, - "foo": { - "name": "foo", - "type": { - "name": "string", - }, - }, - }, - "args": { - "foo": "c", - }, - "component": undefined, - "componentId": "component-two", - "globals": { - "a": "b", - }, - "id": "component-two--c", - "initialArgs": { - "foo": "c", - }, - "kind": "Component Two", - "name": "C", - "parameters": { - "__isArgsStory": false, - "fileName": "./src/ComponentTwo.stories.js", - "throwPlayFunctionExceptions": false, - }, - "playFunction": undefined, - "renderToCanvas": undefined, - "story": "C", - "storyGlobals": {}, - "subcomponents": undefined, - "tags": [ - "dev", - "test", - ], - "testingLibraryRender": undefined, - "title": "Component Two", - "usesMount": false, - }, - }, - "v": 2, - } -`); - }); - }); - - describe('getStoriesJsonData', () => { - describe('in back-compat mode', () => { - it('maps stories list to payload correctly', async () => { - const store = new StoryStore(storyIndex, importFn, projectAnnotations); - await store.cacheAllCSFFiles(); - - expect(store.getStoriesJsonData()).toMatchInlineSnapshot(` - { - "stories": { - "component-one--a": { - "id": "component-one--a", - "importPath": "./src/ComponentOne.stories.js", - "kind": "Component One", - "name": "A", - "parameters": { - "__isArgsStory": false, - "fileName": "./src/ComponentOne.stories.js", - }, - "story": "A", - "title": "Component One", - }, - "component-one--b": { - "id": "component-one--b", - "importPath": "./src/ComponentOne.stories.js", - "kind": "Component One", - "name": "B", - "parameters": { - "__isArgsStory": false, - "fileName": "./src/ComponentOne.stories.js", - }, - "story": "B", - "title": "Component One", - }, - "component-two--c": { - "id": "component-two--c", - "importPath": "./src/ComponentTwo.stories.js", - "kind": "Component Two", - "name": "C", - "parameters": { - "__isArgsStory": false, - "fileName": "./src/ComponentTwo.stories.js", - }, - "story": "C", - "title": "Component Two", - }, - }, - "v": 3, - } - `); - }); - }); - }); }); diff --git a/code/core/src/preview-api/modules/store/StoryStore.ts b/code/core/src/preview-api/modules/store/StoryStore.ts index 2cd9e4c732e..391a70f5b48 100644 --- a/code/core/src/preview-api/modules/store/StoryStore.ts +++ b/code/core/src/preview-api/modules/store/StoryStore.ts @@ -330,56 +330,4 @@ export class StoryStore { {} as Record ); } - - // TODO: Remove in 9.0 - getSetStoriesPayload() { - const stories = this.extract({ includeDocsOnly: true }); - - const kindParameters: Parameters = Object.values(stories).reduce( - (acc: Parameters, { title }: { title: ComponentTitle }) => { - acc[title] = {}; - return acc; - }, - {} as Parameters - ); - - return { - v: 2, - globals: this.userGlobals.get(), - globalParameters: {}, - kindParameters, - stories, - }; - } - - // TODO: Remove in 9.0 - // NOTE: this is legacy `stories.json` data for the `extract` script. - // It is used to allow v7 Storybooks to be composed in v6 Storybooks, which expect a - // `stories.json` file with legacy fields (`kind` etc). - getStoriesJsonData = (): StoryIndexV3 => { - const value = this.getSetStoriesPayload(); - const allowedParameters = ['fileName', 'docsOnly', 'framework', '__id', '__isArgsStory']; - - const stories: Record = mapValues(value.stories, (story) => { - const { importPath } = this.storyIndex.entries[story.id]; - return { - ...picky(story, ['id', 'name', 'title']), - importPath, - // These 3 fields were going to be dropped in v7, but instead we will keep them for the - // 7.x cycle so that v7 Storybooks can be composed successfully in v6 Storybook. - // In v8 we will (likely) completely drop support for `extract` and `getStoriesJsonData` - kind: story.title, - story: story.name, - parameters: { - ...picky(story.parameters, allowedParameters), - fileName: importPath, - }, - } as V3CompatIndexEntry; - }); - - return { - v: 3, - stories, - }; - }; } From ced9aacd3a33c293936bd537ef8df6039630a0da Mon Sep 17 00:00:00 2001 From: Valentin Palkovic Date: Wed, 26 Mar 2025 08:43:57 +0100 Subject: [PATCH 13/37] Remove deprecated `globals` field and related references in project annotations --- code/core/src/csf/story.ts | 2 -- .../modules/store/csf/composeConfigs.ts | 1 - .../csf/normalizeProjectAnnotations.test.ts | 20 +------------------ .../store/csf/normalizeProjectAnnotations.ts | 15 +------------- 4 files changed, 2 insertions(+), 36 deletions(-) diff --git a/code/core/src/csf/story.ts b/code/core/src/csf/story.ts index 9254eaf3c2f..bb15858c106 100644 --- a/code/core/src/csf/story.ts +++ b/code/core/src/csf/story.ts @@ -405,8 +405,6 @@ export interface ProjectAnnotations; diff --git a/code/core/src/preview-api/modules/store/csf/composeConfigs.ts b/code/core/src/preview-api/modules/store/csf/composeConfigs.ts index c36b2aab124..3ed0ac417f2 100644 --- a/code/core/src/preview-api/modules/store/csf/composeConfigs.ts +++ b/code/core/src/preview-api/modules/store/csf/composeConfigs.ts @@ -59,7 +59,6 @@ export function composeConfigs( ...allArgTypeEnhancers.filter((e) => !e.secondPass), ...allArgTypeEnhancers.filter((e) => e.secondPass), ], - globals: getObjectField(moduleExportList, 'globals'), initialGlobals: getObjectField(moduleExportList, 'initialGlobals'), globalTypes: getObjectField(moduleExportList, 'globalTypes'), loaders: getArrayField(moduleExportList, 'loaders'), diff --git a/code/core/src/preview-api/modules/store/csf/normalizeProjectAnnotations.test.ts b/code/core/src/preview-api/modules/store/csf/normalizeProjectAnnotations.test.ts index bfb2a4c067b..a64d143a5fa 100644 --- a/code/core/src/preview-api/modules/store/csf/normalizeProjectAnnotations.test.ts +++ b/code/core/src/preview-api/modules/store/csf/normalizeProjectAnnotations.test.ts @@ -1,26 +1,8 @@ -import { beforeEach, describe, expect, it, vi } from 'vitest'; +import { describe, expect, it } from 'vitest'; import { normalizeProjectAnnotations } from './normalizeProjectAnnotations'; describe('normalizeProjectAnnotations', () => { - describe('blah', () => { - beforeEach(() => { - const warnThatThrows = vi.mocked(console.warn).getMockImplementation(); - vi.mocked(console.warn).mockImplementation(() => {}); - return () => { - vi.mocked(console.warn).mockImplementation(warnThatThrows!); - }; - }); - it('normalizes globals to initialGlobals', () => { - expect( - normalizeProjectAnnotations({ - globals: { a: 'b' }, - }) - ).toMatchObject({ - initialGlobals: { a: 'b' }, - }); - }); - }); it('passes through initialGlobals', () => { expect( normalizeProjectAnnotations({ diff --git a/code/core/src/preview-api/modules/store/csf/normalizeProjectAnnotations.ts b/code/core/src/preview-api/modules/store/csf/normalizeProjectAnnotations.ts index 636520cd4be..e3db75abf4b 100644 --- a/code/core/src/preview-api/modules/store/csf/normalizeProjectAnnotations.ts +++ b/code/core/src/preview-api/modules/store/csf/normalizeProjectAnnotations.ts @@ -1,4 +1,3 @@ -import { deprecate } from 'storybook/internal/client-logger'; import type { ArgTypes, NormalizedProjectAnnotations, @@ -6,11 +5,8 @@ import type { Renderer, } from 'storybook/internal/types'; -import { dedent } from 'ts-dedent'; - import { inferArgTypes } from '../inferArgTypes'; import { inferControls } from '../inferControls'; -import { combineParameters } from '../parameters'; import { normalizeArrays } from './normalizeArrays'; import { normalizeInputTypes } from './normalizeInputTypes'; @@ -26,18 +22,9 @@ export function normalizeProjectAnnotations({ loaders, beforeEach, experimental_afterEach, - globals, initialGlobals, ...annotations }: ProjectAnnotations): NormalizedProjectAnnotations { - if (globals && Object.keys(globals).length > 0) { - deprecate(dedent` - The preview.js 'globals' field is deprecated and will be removed in Storybook 9.0. - Please use 'initialGlobals' instead. Learn more: - - https://github.com/storybookjs/storybook/blob/next/MIGRATION.md#previewjs-globals-renamed-to-initialglobals - `); - } return { ...(argTypes && { argTypes: normalizeInputTypes(argTypes as ArgTypes) }), ...(globalTypes && { globalTypes: normalizeInputTypes(globalTypes) }), @@ -65,7 +52,7 @@ export function normalizeProjectAnnotations({ // TODO: Make an architectural decision on the handling of core addons inferControls, ], - initialGlobals: combineParameters(initialGlobals, globals), + initialGlobals, ...(annotations as NormalizedProjectAnnotations), }; } From 149b8de8871923d1467fd24cd93ecb3b9ee9f623 Mon Sep 17 00:00:00 2001 From: Valentin Palkovic Date: Wed, 26 Mar 2025 08:44:46 +0100 Subject: [PATCH 14/37] Remove deprecated serverChannel property from Preview class --- code/core/src/preview-api/modules/preview-web/Preview.tsx | 3 --- 1 file changed, 3 deletions(-) diff --git a/code/core/src/preview-api/modules/preview-web/Preview.tsx b/code/core/src/preview-api/modules/preview-web/Preview.tsx index 09f36d401a7..d9ebef40736 100644 --- a/code/core/src/preview-api/modules/preview-web/Preview.tsx +++ b/code/core/src/preview-api/modules/preview-web/Preview.tsx @@ -56,9 +56,6 @@ const STORY_INDEX_PATH = './index.json'; export type MaybePromise = Promise | T; export class Preview { - /** @deprecated Will be removed in 8.0, please use channel instead */ - serverChannel?: Channel; - protected storyStoreValue?: StoryStore; renderToCanvas?: RenderToCanvas; From 612db21e813152a8d317b6fe5a74d6beff40c7e0 Mon Sep 17 00:00:00 2001 From: Valentin Palkovic Date: Wed, 26 Mar 2025 08:47:33 +0100 Subject: [PATCH 15/37] Update rendering references to use `renderToCanvas` instead of deprecated `renderToDOM` in documentation and code interfaces. --- code/core/src/preview-api/README-preview-web.md | 2 +- code/core/src/preview-api/modules/store/csf/composeConfigs.ts | 1 - code/core/src/preview/README.md | 2 +- code/core/src/types/modules/story.ts | 2 -- 4 files changed, 2 insertions(+), 5 deletions(-) diff --git a/code/core/src/preview-api/README-preview-web.md b/code/core/src/preview-api/README-preview-web.md index e5c237775ce..61c748838f5 100644 --- a/code/core/src/preview-api/README-preview-web.md +++ b/code/core/src/preview-api/README-preview-web.md @@ -30,7 +30,7 @@ A rendering story goes through these phases: - `preparing` - (maybe async) import the story file and prepare the story function. - `loading` - async loaders are running -- `rendering` - the `renderToDOM` function for the framework is running +- `rendering` - the `renderToCanvas` function for the framework is running - `playing` - the `play` function is running - `completed` - the story is done. diff --git a/code/core/src/preview-api/modules/store/csf/composeConfigs.ts b/code/core/src/preview-api/modules/store/csf/composeConfigs.ts index 3ed0ac417f2..f2fe0cf9da2 100644 --- a/code/core/src/preview-api/modules/store/csf/composeConfigs.ts +++ b/code/core/src/preview-api/modules/store/csf/composeConfigs.ts @@ -67,7 +67,6 @@ export function composeConfigs( experimental_afterEach: getArrayField(moduleExportList, 'experimental_afterEach'), render: getSingletonField(moduleExportList, 'render'), renderToCanvas: getSingletonField(moduleExportList, 'renderToCanvas'), - renderToDOM: getSingletonField(moduleExportList, 'renderToDOM'), // deprecated applyDecorators: getSingletonField(moduleExportList, 'applyDecorators'), runStep: composeStepRunners(stepRunners), tags: getArrayField(moduleExportList, 'tags'), diff --git a/code/core/src/preview/README.md b/code/core/src/preview/README.md index e5c237775ce..61c748838f5 100644 --- a/code/core/src/preview/README.md +++ b/code/core/src/preview/README.md @@ -30,7 +30,7 @@ A rendering story goes through these phases: - `preparing` - (maybe async) import the story file and prepare the story function. - `loading` - async loaders are running -- `rendering` - the `renderToDOM` function for the framework is running +- `rendering` - the `renderToCanvas` function for the framework is running - `playing` - the `play` function is running - `completed` - the story is done. diff --git a/code/core/src/types/modules/story.ts b/code/core/src/types/modules/story.ts index 187bf3af767..2648f46b7c0 100644 --- a/code/core/src/types/modules/story.ts +++ b/code/core/src/types/modules/story.ts @@ -46,8 +46,6 @@ export interface ProjectAnnotations addons?: ProjectAnnotations[]; testingLibraryRender?: (...args: never[]) => { unmount: () => void }; renderToCanvas?: RenderToCanvas; - /* @deprecated use renderToCanvas */ - renderToDOM?: RenderToCanvas; } type NamedExportsOrDefault = TExport | { default: TExport }; From 913d2d433e695303fe7b4ddacbd0f24f2e78b723 Mon Sep 17 00:00:00 2001 From: Valentin Palkovic Date: Wed, 26 Mar 2025 08:50:13 +0100 Subject: [PATCH 16/37] Refactor imports to remove deprecated references to SupportedRenderers in project_types and update related files accordingly --- code/core/src/cli/dirs.ts | 2 +- code/core/src/cli/helpers.test.ts | 2 +- code/core/src/cli/project_types.ts | 8 +------- 3 files changed, 3 insertions(+), 9 deletions(-) diff --git a/code/core/src/cli/dirs.ts b/code/core/src/cli/dirs.ts index a75c1f90d9f..16d32e4a3e3 100644 --- a/code/core/src/cli/dirs.ts +++ b/code/core/src/cli/dirs.ts @@ -3,13 +3,13 @@ import { dirname, join } from 'node:path'; import { temporaryDirectory, versions } from 'storybook/internal/common'; import type { JsPackageManager } from 'storybook/internal/common'; import type { SupportedFrameworks } from 'storybook/internal/types'; +import type { SupportedRenderers } from 'storybook/internal/types'; import downloadTarballDefault from '@ndelangen/get-tarball'; import getNpmTarballUrlDefault from 'get-npm-tarball-url'; import invariant from 'tiny-invariant'; import { externalFrameworks } from './project_types'; -import type { SupportedRenderers } from './project_types'; const resolveUsingBranchInstall = async (packageManager: JsPackageManager, request: string) => { const tempDirectory = await temporaryDirectory(); diff --git a/code/core/src/cli/helpers.test.ts b/code/core/src/cli/helpers.test.ts index f161f4469ca..5bd5d9719f5 100644 --- a/code/core/src/cli/helpers.test.ts +++ b/code/core/src/cli/helpers.test.ts @@ -4,12 +4,12 @@ import fsp from 'node:fs/promises'; import { beforeEach, describe, expect, it, vi } from 'vitest'; import type { JsPackageManager } from 'storybook/internal/common'; +import type { SupportedRenderers } from 'storybook/internal/types'; import { sep } from 'path'; import { IS_WINDOWS } from '../../../vitest.helpers'; import * as helpers from './helpers'; -import type { SupportedRenderers } from './project_types'; import { SupportedLanguage } from './project_types'; const normalizePath = (path: string) => (IS_WINDOWS ? path.replace(/\//g, sep) : path); diff --git a/code/core/src/cli/project_types.ts b/code/core/src/cli/project_types.ts index ab72e282e16..31f27d0e3d2 100644 --- a/code/core/src/cli/project_types.ts +++ b/code/core/src/cli/project_types.ts @@ -1,7 +1,4 @@ -import type { - SupportedRenderers as CoreSupportedRenderers, - SupportedFrameworks, -} from 'storybook/internal/types'; +import type { SupportedFrameworks, SupportedRenderers } from 'storybook/internal/types'; import { minVersion, validRange } from 'semver'; @@ -32,9 +29,6 @@ export const externalFrameworks: ExternalFramework[] = [ }, ]; -/** @deprecated Please use `SupportedRenderers` from `storybook/internal/types` instead */ -export type SupportedRenderers = CoreSupportedRenderers; - export const SUPPORTED_RENDERERS: SupportedRenderers[] = [ 'react', 'react-native', From d31c4b7659c2716d523eaf6a68de96b3100edf37 Mon Sep 17 00:00:00 2001 From: Valentin Palkovic Date: Wed, 26 Mar 2025 09:09:21 +0100 Subject: [PATCH 17/37] Update globals/exports.ts --- code/core/src/manager/globals/exports.ts | 5 ----- 1 file changed, 5 deletions(-) diff --git a/code/core/src/manager/globals/exports.ts b/code/core/src/manager/globals/exports.ts index 3a0099ad471..c567d386935 100644 --- a/code/core/src/manager/globals/exports.ts +++ b/code/core/src/manager/globals/exports.ts @@ -492,7 +492,6 @@ export default { 'H6', 'HR', 'IconButton', - 'Icons', 'Img', 'LI', 'Link', @@ -511,7 +510,6 @@ export default { 'Span', 'StorybookIcon', 'StorybookLogo', - 'Symbols', 'SyntaxHighlighter', 'TT', 'TabBar', @@ -531,7 +529,6 @@ export default { 'components', 'createCopyToClipboardFunction', 'getStoryHref', - 'icons', 'interleaveSeparators', 'nameSpaceClassNames', 'resetComponents', @@ -593,7 +590,6 @@ export default { 'TESTING_MODULE_CANCEL_TEST_RUN_RESPONSE', 'TESTING_MODULE_CRASH_REPORT', 'TESTING_MODULE_PROGRESS_REPORT', - 'TESTING_MODULE_RUN_ALL_REQUEST', 'TESTING_MODULE_RUN_REQUEST', 'TOGGLE_WHATS_NEW_NOTIFICATIONS', 'UNHANDLED_ERRORS_WHILE_PLAYING', @@ -657,7 +653,6 @@ export default { 'TESTING_MODULE_CANCEL_TEST_RUN_RESPONSE', 'TESTING_MODULE_CRASH_REPORT', 'TESTING_MODULE_PROGRESS_REPORT', - 'TESTING_MODULE_RUN_ALL_REQUEST', 'TESTING_MODULE_RUN_REQUEST', 'TOGGLE_WHATS_NEW_NOTIFICATIONS', 'UNHANDLED_ERRORS_WHILE_PLAYING', From f61403a20f647e75446033346434b90247f4e5e5 Mon Sep 17 00:00:00 2001 From: Valentin Palkovic Date: Wed, 26 Mar 2025 09:21:19 +0100 Subject: [PATCH 18/37] Remove deprecated comment from Addon_BaseMeta interface in addons.ts --- code/core/src/types/modules/addons.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/code/core/src/types/modules/addons.ts b/code/core/src/types/modules/addons.ts index aa923505097..0fef98cab33 100644 --- a/code/core/src/types/modules/addons.ts +++ b/code/core/src/types/modules/addons.ts @@ -288,7 +288,6 @@ export interface Addon_BaseMeta { * * Used by addons for automatic prop table generation and display of other component metadata. * - * @deprecated * @example * * ```ts From 36cf6435b7024943100d71b8d7450ab709232db8 Mon Sep 17 00:00:00 2001 From: Valentin Palkovic Date: Wed, 26 Mar 2025 13:08:24 +0100 Subject: [PATCH 19/37] Update addon/designs --- code/package.json | 2 +- code/yarn.lock | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/code/package.json b/code/package.json index 8554f4ae79c..4d96426cfb7 100644 --- a/code/package.json +++ b/code/package.json @@ -103,7 +103,7 @@ "@playwright/test": "1.48.1", "@storybook/addon-a11y": "workspace:*", "@storybook/addon-backgrounds": "workspace:*", - "@storybook/addon-designs": "9.0.0--canary.1499c1a.0", + "@storybook/addon-designs": "9.0.0-next.1", "@storybook/addon-docs": "workspace:*", "@storybook/addon-essentials": "workspace:*", "@storybook/addon-highlight": "workspace:*", diff --git a/code/yarn.lock b/code/yarn.lock index c7722331d3b..c70a1e63b4a 100644 --- a/code/yarn.lock +++ b/code/yarn.lock @@ -6083,9 +6083,9 @@ __metadata: languageName: unknown linkType: soft -"@storybook/addon-designs@npm:9.0.0--canary.1499c1a.0": - version: 9.0.0--canary.1499c1a.0 - resolution: "@storybook/addon-designs@npm:9.0.0--canary.1499c1a.0" +"@storybook/addon-designs@npm:9.0.0-next.1": + version: 9.0.0-next.1 + resolution: "@storybook/addon-designs@npm:9.0.0-next.1" dependencies: "@figspec/react": "npm:^1.0.0" peerDependencies: @@ -6099,7 +6099,7 @@ __metadata: optional: true react-dom: optional: true - checksum: 10c0/5fd56ad8832778590f1bcdd144c17c234482a137475747e8791e4be9a4ba7132a6089287a614586b86d06b6082de932ee19a8709f39888077cbac98bc60b3705 + checksum: 10c0/6989444d6caeb7abbb1a763e0a29d0749c529216d03d690618575378845e4259ddcf1935f7990fb05667a373940086dbacdcc6c97ff3f11eaa76f132bb11a1d5 languageName: node linkType: hard @@ -7160,7 +7160,7 @@ __metadata: "@playwright/test": "npm:1.48.1" "@storybook/addon-a11y": "workspace:*" "@storybook/addon-backgrounds": "workspace:*" - "@storybook/addon-designs": "npm:9.0.0--canary.1499c1a.0" + "@storybook/addon-designs": "npm:9.0.0-next.1" "@storybook/addon-docs": "workspace:*" "@storybook/addon-essentials": "workspace:*" "@storybook/addon-highlight": "workspace:*" From ae7e69e65682a3cbafbd166808acc9945b0fce9b Mon Sep 17 00:00:00 2001 From: Valentin Palkovic Date: Wed, 26 Mar 2025 13:09:07 +0100 Subject: [PATCH 20/37] Refactor StoryStore access in Storybook preview to use the new StoryStore instance and remove deprecated proxy method --- code/.storybook/preview.tsx | 13 +++++++----- .../modules/preview-web/Preview.tsx | 21 ------------------- 2 files changed, 8 insertions(+), 26 deletions(-) diff --git a/code/.storybook/preview.tsx b/code/.storybook/preview.tsx index 73155fe33fa..232b9a4cff2 100644 --- a/code/.storybook/preview.tsx +++ b/code/.storybook/preview.tsx @@ -17,7 +17,7 @@ import addonTest from '@storybook/addon-test'; import addonThemes from '@storybook/addon-themes'; import { DocsContext as DocsContextProps, useArgs } from 'storybook/preview-api'; -import type { PreviewWeb } from 'storybook/preview-api'; +import type { PreviewWeb, StoryStore } from 'storybook/preview-api'; import { Global, ThemeProvider, @@ -146,9 +146,12 @@ const loaders = [ // eslint-disable-next-line no-underscore-dangle const preview = (window as any).__STORYBOOK_PREVIEW__ as PreviewWeb | undefined; const channel = (window as any).__STORYBOOK_ADDONS_CHANNEL__ as Channel | undefined; + const storyStore = (window as any).__STORYBOOK_STORY_STORE__ as + | StoryStore + | undefined; // __STORYBOOK_PREVIEW__ and __STORYBOOK_ADDONS_CHANNEL__ is set in the PreviewWeb constructor // which isn't loaded in portable stories/vitest - if (!relativeCsfPaths || !preview || !channel) { + if (!relativeCsfPaths || !preview || !channel || !storyStore) { return {}; } const csfFiles = await Promise.all( @@ -157,7 +160,7 @@ const loaders = [ /^..\//, '' )}.tsx`; - const entry = preview.storyStore.storyIndex?.importPathToEntry(projectRelativePath); + const entry = storyStore.storyIndex?.importPathToEntry(projectRelativePath); if (!entry) { throw new Error( @@ -165,12 +168,12 @@ const loaders = [ ); } - return preview.storyStore.loadCSFFileByStoryId(entry.id); + return storyStore.loadCSFFileByStoryId(entry.id); }) ); const docsContext = new DocsContextProps( channel, - preview.storyStore, + storyStore, preview.renderStoryToElement.bind(preview), csfFiles ); diff --git a/code/core/src/preview-api/modules/preview-web/Preview.tsx b/code/core/src/preview-api/modules/preview-web/Preview.tsx index d9ebef40736..b31152c1bda 100644 --- a/code/core/src/preview-api/modules/preview-web/Preview.tsx +++ b/code/core/src/preview-api/modules/preview-web/Preview.tsx @@ -98,27 +98,6 @@ export class Preview { } } - // Create a proxy object for `__STORYBOOK_STORY_STORE__` and `__STORYBOOK_PREVIEW__.storyStore` - // That proxies through to the store once ready, and errors beforehand. This means we can set - // `__STORYBOOK_STORY_STORE__ = __STORYBOOK_PREVIEW__.storyStore` without having to wait, and - // similarly integrators can access the `storyStore` on the preview at any time, although - // it is considered deprecated and we will no longer allow access in 9.0 - get storyStore() { - return new Proxy( - {}, - { - get: (_, method) => { - if (this.storyStoreValue) { - deprecate('Accessing the Story Store is deprecated and will be removed in 9.0'); - return this.storyStoreValue[method as keyof StoryStore]; - } - - throw new StoryStoreAccessedBeforeInitializationError(); - }, - } - ) as StoryStore; - } - // INITIALIZATION protected async initialize() { this.setupListeners(); From dbb7754814f80339c8e1720b6813581fb4107832 Mon Sep 17 00:00:00 2001 From: Valentin Palkovic Date: Wed, 26 Mar 2025 13:09:20 +0100 Subject: [PATCH 21/37] Refactor composeStory function to update TODO comments for future consolidation of renderContext and context in SB 10.0, and remove deprecated loading from globalTypes. --- .../preview-api/modules/store/csf/portable-stories.ts | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/code/core/src/preview-api/modules/store/csf/portable-stories.ts b/code/core/src/preview-api/modules/store/csf/portable-stories.ts index 339ad004685..d3c8daa9b81 100644 --- a/code/core/src/preview-api/modules/store/csf/portable-stories.ts +++ b/code/core/src/preview-api/modules/store/csf/portable-stories.ts @@ -29,7 +29,6 @@ import { HooksContext } from '../../../addons'; import { ReporterAPI } from '../reporter-api'; import { composeConfigs } from './composeConfigs'; import { getCsfFactoryAnnotations } from './csf-factory-utils'; -import { getValuesFromArgTypes } from './getValuesFromArgTypes'; import { normalizeComponentAnnotations } from './normalizeComponentAnnotations'; import { normalizeProjectAnnotations } from './normalizeProjectAnnotations'; import { normalizeStory } from './normalizeStory'; @@ -134,10 +133,7 @@ export function composeStory { - // Consolidate this renderContext with Context in SB 9.0 + // TODO: Consolidate this renderContext with Context in SB 10.0 + // Change renderToCanvas function to only use the context object + // and to make the renderContext an internal implementation detail + // wasnt'possible so far because showError and showException are not part of the story context (yet) const unmount = await story.renderToCanvas?.( { componentId: story.componentId, From f0c6d810f0bca072af3ddecd3f671079b1849723 Mon Sep 17 00:00:00 2001 From: Valentin Palkovic Date: Wed, 26 Mar 2025 13:09:39 +0100 Subject: [PATCH 22/37] Update TODO comment in portable-stories-legacy test to reflect potential removal in Storybook 9.0 with CSF4 integration. --- .../react/src/__test__/portable-stories-legacy.test.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/renderers/react/src/__test__/portable-stories-legacy.test.tsx b/code/renderers/react/src/__test__/portable-stories-legacy.test.tsx index 9a328078324..2537ac0dedd 100644 --- a/code/renderers/react/src/__test__/portable-stories-legacy.test.tsx +++ b/code/renderers/react/src/__test__/portable-stories-legacy.test.tsx @@ -13,7 +13,7 @@ import { composeStories, composeStory, setProjectAnnotations } from '..'; import type { Button } from './Button'; import * as stories from './Button.stories'; -// TODO: Potentially remove this in Storybook 9.0 once we fully move users to the new portable stories API +// TODO: Potentially remove this in Storybook 9.0 once we fully move users to the new portable stories API (with CSF4) describe('Legacy Portable Stories API', () => { // example with composeStories, returns an object with all stories composed with args/decorators const { CSF3Primary, LoaderStory } = composeStories(stories); From dd0f2d8a4ce8af5b85dd1f04f40b5a695456d316 Mon Sep 17 00:00:00 2001 From: Valentin Palkovic Date: Wed, 26 Mar 2025 13:09:44 +0100 Subject: [PATCH 23/37] Remove deprecated hasInteractiveStories function from baseGenerator.ts --- code/lib/create-storybook/src/generators/baseGenerator.ts | 3 --- 1 file changed, 3 deletions(-) diff --git a/code/lib/create-storybook/src/generators/baseGenerator.ts b/code/lib/create-storybook/src/generators/baseGenerator.ts index d55e26b2847..b87246af1c4 100644 --- a/code/lib/create-storybook/src/generators/baseGenerator.ts +++ b/code/lib/create-storybook/src/generators/baseGenerator.ts @@ -183,9 +183,6 @@ const getFrameworkDetails = ( const stripVersions = (addons: string[]) => addons.map((addon) => getPackageDetails(addon)[0]); -const hasInteractiveStories = (rendererId: SupportedRenderers) => - ['react', 'angular', 'preact', 'svelte', 'vue3', 'html', 'solid', 'qwik'].includes(rendererId); - const hasFrameworkTemplates = (framework?: SupportedFrameworks) => { if (!framework) { return false; From 4f4806fc2b329c4f9456bbf606b77926ffbeaf45 Mon Sep 17 00:00:00 2001 From: Valentin Palkovic Date: Wed, 26 Mar 2025 13:09:50 +0100 Subject: [PATCH 24/37] Refactor imports in toolbar components to use updated IconsProps path --- code/core/src/toolbar/components/ToolbarMenuButton.tsx | 4 +++- code/core/src/toolbar/types.ts | 3 ++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/code/core/src/toolbar/components/ToolbarMenuButton.tsx b/code/core/src/toolbar/components/ToolbarMenuButton.tsx index 05a07d87989..5c55e63c0f1 100644 --- a/code/core/src/toolbar/components/ToolbarMenuButton.tsx +++ b/code/core/src/toolbar/components/ToolbarMenuButton.tsx @@ -1,6 +1,8 @@ import React, { type FC } from 'react'; -import { IconButton, Icons, type IconsProps } from 'storybook/internal/components'; +import { IconButton } from 'storybook/internal/components'; + +import { Icons, type IconsProps } from '../../components/components/icon/icon'; interface ToolbarMenuButtonProps { active: boolean; diff --git a/code/core/src/toolbar/types.ts b/code/core/src/toolbar/types.ts index fb88149e207..ce8fb93c734 100644 --- a/code/core/src/toolbar/types.ts +++ b/code/core/src/toolbar/types.ts @@ -1,6 +1,7 @@ -import type { IconsProps } from 'storybook/internal/components'; import type { InputType } from 'storybook/internal/types'; +import type { IconsProps } from '../components/components/icon/icon'; + export type ToolbarShortcutType = 'next' | 'previous' | 'reset'; export type ToolbarItemType = 'item' | 'reset'; From fcf572f73b7fbb8ef5b66c5eb58c4b80b0b0bf4f Mon Sep 17 00:00:00 2001 From: Valentin Palkovic Date: Wed, 26 Mar 2025 13:15:37 +0100 Subject: [PATCH 25/37] Remove deprecated Button stories and update Button component to eliminate deprecated props, ensuring compatibility with future Storybook versions. --- .../Button/Button.deprecated.stories.tsx | 93 ------------------- .../components/components/Button/Button.tsx | 65 +------------ .../manager/components/sidebar/RefBlocks.tsx | 5 +- 3 files changed, 4 insertions(+), 159 deletions(-) delete mode 100644 code/core/src/components/components/Button/Button.deprecated.stories.tsx diff --git a/code/core/src/components/components/Button/Button.deprecated.stories.tsx b/code/core/src/components/components/Button/Button.deprecated.stories.tsx deleted file mode 100644 index fe7ebd265cc..00000000000 --- a/code/core/src/components/components/Button/Button.deprecated.stories.tsx +++ /dev/null @@ -1,93 +0,0 @@ -import React from 'react'; - -import { LinkIcon } from '@storybook/icons'; - -import type { Meta, StoryObj } from '@storybook/react-vite'; - -import { Form } from '../form'; -import { Button } from './Button'; - -const meta: Meta = { - title: 'Button (Deprecated)', - component: Button, - tags: ['autodocs'], -}; - -export default meta; -type Story = StoryObj; - -export const Default = { args: { children: 'Default' } }; - -export const FormButton: Story = { - render: (args) => , - args: { children: 'Form.Button' }, -}; - -export const Primary: Story = { args: { primary: true, children: 'Primary' } }; -export const Secondary: Story = { args: { secondary: true, children: 'Secondary' } }; -export const Tertiary: Story = { args: { tertiary: true, children: 'Tertiary' } }; -export const Gray: Story = { args: { gray: true, children: 'Gray' } }; - -export const Outline: Story = { args: { outline: true, children: 'Outline' } }; -export const OutlinePrimary: Story = { - args: { outline: true, primary: true, children: 'Outline Primary' }, -}; -export const OutlineSecondary: Story = { - args: { outline: true, secondary: true, children: 'Outline Secondary' }, -}; -export const OutlineTertiary: Story = { - args: { outline: true, tertiary: true, children: 'Outline Tertiary' }, -}; - -export const Disabled: Story = { args: { disabled: true, children: 'Disabled' } }; -export const DisabledPrimary: Story = { - args: { disabled: true, primary: true, children: 'Disabled Priary' }, -}; -export const DisabledSecondary: Story = { - args: { disabled: true, secondary: true, children: 'Disabled Secondary' }, -}; -export const DisabledTertiary: Story = { - args: { disabled: true, tertiary: true, children: 'Disabled Tertiary' }, -}; -export const DisabledGray: Story = { - args: { disabled: true, gray: true, children: 'Disabled Gray' }, -}; - -export const Small: Story = { args: { small: true, children: 'Small' } }; -export const SmallPrimary: Story = { - args: { small: true, primary: true, children: 'Small Priary' }, -}; -export const SmallSecondary: Story = { - args: { small: true, secondary: true, children: 'Small Secondary' }, -}; -export const SmallTertiary: Story = { - args: { small: true, tertiary: true, children: 'Small Tertiary' }, -}; -export const SmallGray: Story = { - args: { small: true, gray: true, children: 'Small Gray' }, -}; - -export const IsLink: Story = { - args: { isLink: true, children: 'Button as a link' }, -}; - -export const IconPrimary: Story = { - args: { - primary: true, - containsIcon: true, - title: 'link', - children: , - }, -}; -export const IconOutline: Story = { - args: { outline: true, containsIcon: true, title: 'link', children: }, -}; -export const IconOutlineSmall: Story = { - args: { - outline: true, - containsIcon: true, - small: true, - title: 'link', - children: , - }, -}; diff --git a/code/core/src/components/components/Button/Button.tsx b/code/core/src/components/components/Button/Button.tsx index 8c77f173c80..6aecce3905d 100644 --- a/code/core/src/components/components/Button/Button.tsx +++ b/code/core/src/components/components/Button/Button.tsx @@ -1,8 +1,6 @@ import type { ButtonHTMLAttributes, SyntheticEvent } from 'react'; import React, { forwardRef, useEffect, useState } from 'react'; -import { deprecate } from 'storybook/internal/client-logger'; - import { Slot } from '@radix-ui/react-slot'; import { darken, lighten, rgba, transparentize } from 'polished'; import { isPropValid, styled } from 'storybook/theming'; @@ -16,25 +14,6 @@ export interface ButtonProps extends ButtonHTMLAttributes { disabled?: boolean; active?: boolean; animation?: 'none' | 'rotate360' | 'glow' | 'jiggle'; - - /** @deprecated Use {@link asChild} instead. This will be removed in Storybook 9.0 */ - isLink?: boolean; - /** @deprecated Use {@link variant} instead. This will be removed in Storybook 9.0 */ - primary?: boolean; - /** @deprecated Use {@link variant} instead. This will be removed in Storybook 9.0 */ - secondary?: boolean; - /** @deprecated Use {@link variant} instead. This will be removed in Storybook 9.0 */ - tertiary?: boolean; - /** @deprecated Use {@link variant} instead. This will be removed in Storybook 9.0 */ - gray?: boolean; - /** @deprecated Use {@link variant} instead. This will be removed in Storybook 9.0 */ - inForm?: boolean; - /** @deprecated Use {@link size} instead. This will be removed in Storybook 9.0 */ - small?: boolean; - /** @deprecated Use {@link variant} instead. This will be removed in Storybook 9.0 */ - outline?: boolean; - /** @deprecated Add your icon as a child directly. This will be removed in Storybook 9.0 */ - containsIcon?: boolean; } export const Button = forwardRef( @@ -54,15 +33,11 @@ export const Button = forwardRef( ) => { let Comp: 'button' | 'a' | typeof Slot = 'button'; - if (props.isLink) { - Comp = 'a'; - } - if (asChild) { Comp = Slot; } - let localVariant = variant; - let localSize = size; + const localVariant = variant; + const localSize = size; const [isAnimating, setIsAnimating] = useState(false); @@ -86,42 +61,6 @@ export const Button = forwardRef( return () => clearTimeout(timer); }, [isAnimating]); - // Match the old API with the new API. - // TODO: Remove this after 9.0. - if (props.primary) { - localVariant = 'solid'; - localSize = 'medium'; - } - - // Match the old API with the new API. - // TODO: Remove this after 9.0. - if (props.secondary || props.tertiary || props.gray || props.outline || props.inForm) { - localVariant = 'outline'; - localSize = 'medium'; - } - - if ( - props.small || - props.isLink || - props.primary || - props.secondary || - props.tertiary || - props.gray || - props.outline || - props.inForm || - props.containsIcon - ) { - const buttonContent = React.Children.toArray(props.children).filter( - (e) => typeof e === 'string' && e !== '' - ); - - deprecate( - `Use of deprecated props in the button ${ - buttonContent.length > 0 ? `"${buttonContent.join(' ')}"` : 'component' - } detected, see the migration notes at https://github.com/storybookjs/storybook/blob/next/MIGRATION.md#new-ui-and-props-for-button-and-iconbutton-components` - ); - } - return ( = ({ loginUrl, id } this Storybook.

- {/* TODO: Make sure this button is working without the deprecated props */} - @@ -92,7 +91,7 @@ export const AuthBlock: FC<{ loginUrl: string; id: string }> = ({ loginUrl, id } Sign in to browse this Storybook.
{/* @ts-expect-error (non strict) */} - From e8accf3ad08943121a265ed7fd0801f7edcd8ed7 Mon Sep 17 00:00:00 2001 From: Valentin Palkovic Date: Wed, 26 Mar 2025 13:28:35 +0100 Subject: [PATCH 26/37] Add Migration guide --- MIGRATION.md | 118 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 118 insertions(+) diff --git a/MIGRATION.md b/MIGRATION.md index 1ee3609cbad..b1c6c01f961 100644 --- a/MIGRATION.md +++ b/MIGRATION.md @@ -1,6 +1,15 @@

Migration

- [From version 8.x to 9.0.0](#from-version-8x-to-900) + - [Button Component API Changes](#button-component-api-changes) + - [Documentation Generation Changes](#documentation-generation-changes) + - [Global State Management](#global-state-management) + - [Icon System Updates](#icon-system-updates) + - [Sidebar Component Changes](#sidebar-component-changes) + - [Testing Module Changes](#testing-module-changes) + - [Type System Updates](#type-system-updates) + - [Story Store API Changes](#story-store-api-changes) + - [CSF File Changes](#csf-file-changes) - [The parameter docs.source.excludeDecorators has no effect in React](#the-parameter-docssourceexcludedecorators-has-no-effect-in-react) - [Addon Viewport is moved to core](#addon-viewport-is-moved-to-core) - [Addon Controls is moved to core](#addon-controls-is-moved-to-core) @@ -412,6 +421,115 @@ ## From version 8.x to 9.0.0 +### Button Component API Changes + +The Button component has been updated to use a more modern props API. The following props have been removed: +- `isLink` +- `primary` +- `secondary` +- `tertiary` +- `gray` +- `inForm` +- `small` +- `outline` +- `containsIcon` + +Use the new `variant` and `size` props instead: + +```diff +- ++ +``` + +### Documentation Generation Changes + +The `autodocs` configuration option has been removed in favor of using tags: + +```diff +// .storybook/preview.js +export default { +- docs: { autodocs: true } +}; + +// In your CSF files: ++ export default { ++ tags: ['autodocs'] ++ }; +``` + +### Global State Management + +The `globals` field in project annotations has been renamed to `initialGlobals`: + +```diff +export const preview = { +- globals: { ++ initialGlobals: { + theme: 'light' + } +}; +``` + +Additionally loading `globals` from globalTypes isn't supported in portable stories anymore. Use `initialGlobals` instead. + +### Icon System Updates + +Several icon-related exports have been removed: +- `IconButtonSkeleton` +- `Icons` +- `Symbols` +- Legacy icon exports + +Use the new icon system from `@storybook/icons` instead: + +```diff +- import { Icons, IconButtonSkeleton } from '@storybook/components'; ++ import { ZoomIcon } from '@storybook/icons'; +``` + +### Sidebar Component Changes + +1. The 'extra' prop has been removed from the Sidebar's Heading component +2. Experimental sidebar features have been removed: + - `experimental_SIDEBAR_BOTTOM` + - `experimental_SIDEBAR_TOP` + +### Testing Module Changes + +The `TESTING_MODULE_RUN_ALL_REQUEST` event has been removed: + +```diff +- import { TESTING_MODULE_RUN_ALL_REQUEST } from '@storybook/core-events'; ++ import { TESTING_MODULE_RUN_REQUEST } from '@storybook/core-events'; +``` + +### Type System Updates + +The following types have been removed: +- `Addon_SidebarBottomType` +- `Addon_SidebarTopType` +- `DeprecatedState` + +Import paths have been updated: +```diff +- import { SupportedRenderers } from './project_types'; ++ import { SupportedRenderers } from 'storybook/internal/types'; +``` + +### Story Store API Changes + +Several deprecated methods have been removed from the StoryStore: +- `getSetStoriesPayload` +- `getStoriesJsonData` +- `raw` +- `fromId` + +### CSF File Changes + +Deprecated getters have been removed from the CsfFile class: +- `_fileName` +- `_makeTitle` + ### The parameter docs.source.excludeDecorators has no effect in React In React, the parameter `docs.source.excludeDecorators` option is no longer used. From 3dcc1049339e6a64036c7bd76089236bf75ec13e Mon Sep 17 00:00:00 2001 From: Valentin Palkovic Date: Wed, 26 Mar 2025 13:40:59 +0100 Subject: [PATCH 27/37] Fix portable stories --- .../react/stories/Button.stories.playwright.ts | 2 +- .../vue3/stories/Button.stories.portable.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/test-storybooks/portable-stories-kitchen-sink/react/stories/Button.stories.playwright.ts b/test-storybooks/portable-stories-kitchen-sink/react/stories/Button.stories.playwright.ts index 242a5dfa1d2..e28c89abdc7 100644 --- a/test-storybooks/portable-stories-kitchen-sink/react/stories/Button.stories.playwright.ts +++ b/test-storybooks/portable-stories-kitchen-sink/react/stories/Button.stories.playwright.ts @@ -5,4 +5,4 @@ export default composeStories(stories); export const SingleComposedStory = composeStory(stories.CSF3Primary, stories.default); -export const WithSpanishGlobal = composeStory(stories.CSF2StoryWithLocale, stories.default, {globals: { locale: 'es' }}); +export const WithSpanishGlobal = composeStory(stories.CSF2StoryWithLocale, stories.default, { initialGlobals: { locale: 'es' } }); diff --git a/test-storybooks/portable-stories-kitchen-sink/vue3/stories/Button.stories.portable.ts b/test-storybooks/portable-stories-kitchen-sink/vue3/stories/Button.stories.portable.ts index 415bff5b4b8..5ae5a563829 100644 --- a/test-storybooks/portable-stories-kitchen-sink/vue3/stories/Button.stories.portable.ts +++ b/test-storybooks/portable-stories-kitchen-sink/vue3/stories/Button.stories.portable.ts @@ -5,4 +5,4 @@ export default composeStories(stories); export const SingleComposedStory = composeStory(stories.CSF3Primary, stories.default); -export const WithSpanishGlobal = composeStory(stories.CSF2StoryWithLocale, stories.default, {globals: { locale: 'es' }}); +export const WithSpanishGlobal = composeStory(stories.CSF2StoryWithLocale, stories.default, {initialGlobals: { locale: 'es' }}); From 1750457a1eb961551e5d5f7780b1095a5bf29bd9 Mon Sep 17 00:00:00 2001 From: Valentin Palkovic Date: Wed, 26 Mar 2025 13:56:28 +0100 Subject: [PATCH 28/37] Update migration guide and refactor portable stories to use initialGlobals for locale configuration instead of globalTypes defaultValue. --- MIGRATION.md | 22 ++++++++++++++++++- .../react/.storybook/preview.tsx | 4 +++- .../react/stories/Button.test.tsx | 2 +- 3 files changed, 25 insertions(+), 3 deletions(-) diff --git a/MIGRATION.md b/MIGRATION.md index b1c6c01f961..8da86425c6d 100644 --- a/MIGRATION.md +++ b/MIGRATION.md @@ -470,7 +470,27 @@ export const preview = { }; ``` -Additionally loading `globals` from globalTypes isn't supported in portable stories anymore. Use `initialGlobals` instead. +Additionally loading the defaultValue from `globalTypes` isn't supported anymore. Use `initialGlobals` instead to define the defaultValue. + +```diff +// .storybook/preview.js +export default { ++ initialGlobals: { ++ locale: 'en' ++ }, + globalTypes: { + locale: { + description: 'Locale for components', +- defaultValue: 'en', + toolbar: { + title: 'Locale', + icon: 'circlehollow', + items: ['es', 'en'], + }, + }, + }, +} +``` ### Icon System Updates diff --git a/test-storybooks/portable-stories-kitchen-sink/react/.storybook/preview.tsx b/test-storybooks/portable-stories-kitchen-sink/react/.storybook/preview.tsx index ca3df4c4743..bcfa84fdb02 100644 --- a/test-storybooks/portable-stories-kitchen-sink/react/.storybook/preview.tsx +++ b/test-storybooks/portable-stories-kitchen-sink/react/.storybook/preview.tsx @@ -12,10 +12,12 @@ const preview: Preview = {
), ], + initialGlobals: { + locale: 'en', + }, globalTypes: { locale: { description: 'Locale for components', - defaultValue: 'en', toolbar: { title: 'Locale', icon: 'circlehollow', diff --git a/test-storybooks/portable-stories-kitchen-sink/react/stories/Button.test.tsx b/test-storybooks/portable-stories-kitchen-sink/react/stories/Button.test.tsx index 1a821c6531b..eb1a1bf2e99 100644 --- a/test-storybooks/portable-stories-kitchen-sink/react/stories/Button.test.tsx +++ b/test-storybooks/portable-stories-kitchen-sink/react/stories/Button.test.tsx @@ -55,7 +55,7 @@ describe('projectAnnotations', () => { it('renders with custom projectAnnotations via composeStory params', () => { const WithPortugueseText = composeStory(stories.CSF2StoryWithLocale, stories.default, { - globalTypes: { locale: { defaultValue: 'pt' } }, + initialGlobals: { locale: 'pt' }, }); const { getByText } = render(); const buttonElement = getByText('Olá!'); From dfd90fce63f3bfcb296e75bf195df961aa964348 Mon Sep 17 00:00:00 2001 From: Valentin Palkovic Date: Wed, 26 Mar 2025 14:27:29 +0100 Subject: [PATCH 29/37] Final cleanup --- code/core/src/controls/manager.tsx | 8 +- .../components/sidebar/Heading.stories.tsx | 23 +++--- .../sidebar/__tests__/Sidebar.test.tsx | 10 +-- .../modules/preview-web/PreviewWeb.test.ts | 75 ++++++++++++++----- .../blocks/src/components/Preview.stories.tsx | 75 +++++++++---------- .../src/automigrate/fixes/vite-config-file.ts | 3 +- .../src/automigrate/helpers/mainConfigFile.ts | 3 +- 7 files changed, 113 insertions(+), 84 deletions(-) diff --git a/code/core/src/controls/manager.tsx b/code/core/src/controls/manager.tsx index 57bad0baa30..64d0785f9b0 100644 --- a/code/core/src/controls/manager.tsx +++ b/code/core/src/controls/manager.tsx @@ -9,6 +9,8 @@ import type { import { SAVE_STORY_REQUEST, SAVE_STORY_RESPONSE } from 'storybook/internal/core-events'; import type { Args } from 'storybook/internal/csf'; +import { FailedIcon, PassedIcon } from '@storybook/icons'; + import { dequal as deepEqual } from 'dequal'; import { addons, experimental_requestResponse, types, useArgTypes } from 'storybook/manager-api'; import { color } from 'storybook/theming'; @@ -71,7 +73,7 @@ addons.register(ADDON_ID, (api) => { api.addNotification({ id: 'save-story-success', - icon: { name: 'passed', color: color.positive }, + icon: , content: { headline: 'Story saved', subHeadline: ( @@ -85,7 +87,7 @@ addons.register(ADDON_ID, (api) => { } catch (error: any) { api.addNotification({ id: 'save-story-error', - icon: { name: 'failed', color: color.negative }, + icon: , content: { headline: 'Failed to save story', subHeadline: @@ -116,7 +118,7 @@ addons.register(ADDON_ID, (api) => { api.addNotification({ id: 'save-story-success', - icon: { name: 'passed', color: color.positive }, + icon: , content: { headline: 'Story created', subHeadline: ( diff --git a/code/core/src/manager/components/sidebar/Heading.stories.tsx b/code/core/src/manager/components/sidebar/Heading.stories.tsx index bcc3d953b78..d74b0a82c09 100644 --- a/code/core/src/manager/components/sidebar/Heading.stories.tsx +++ b/code/core/src/manager/components/sidebar/Heading.stories.tsx @@ -31,7 +31,7 @@ const menuItems = [ ]; export const MenuHighlighted: Story = () => ( - + ); export const standardData = { menu: menuItems }; @@ -50,7 +50,7 @@ export const Standard: Story = () => { }, }} > - + ); }; @@ -69,7 +69,7 @@ export const StandardNoLink: Story = () => { }, }} > - + ); }; @@ -88,7 +88,7 @@ export const LinkAndText: Story = () => { }, }} > - + ); }; @@ -107,7 +107,7 @@ export const OnlyText: Story = () => { }, }} > - + ); }; @@ -126,7 +126,7 @@ export const LongText: Story = () => { }, }} > - + ); }; @@ -145,7 +145,7 @@ export const CustomTitle: Story = () => { }, }} > - + ); }; @@ -164,7 +164,7 @@ export const CustomBrandImage: Story = () => { }, }} > - + ); }; @@ -183,7 +183,7 @@ export const CustomBrandImageTall: Story = () => { }, }} > - + ); }; @@ -202,7 +202,7 @@ export const CustomBrandImageUnsizedSVG: Story = () => { }, }} > - + ); }; @@ -221,7 +221,7 @@ export const NoBrand: Story = () => { }, }} > - + ); }; @@ -230,7 +230,6 @@ export const SkipToCanvasLinkFocused: StoryObj = { args: { menu: menuItems, skipLinkHref: '#storybook-preview-wrapper', - extra: [], isLoading: false, }, globals: { sb_theme: 'light' }, diff --git a/code/core/src/manager/components/sidebar/__tests__/Sidebar.test.tsx b/code/core/src/manager/components/sidebar/__tests__/Sidebar.test.tsx index 726ada568df..060dfaefef6 100644 --- a/code/core/src/manager/components/sidebar/__tests__/Sidebar.test.tsx +++ b/code/core/src/manager/components/sidebar/__tests__/Sidebar.test.tsx @@ -21,15 +21,7 @@ const factory = (props: Partial): RenderResult => { return render( - + ); }; diff --git a/code/core/src/preview-api/modules/preview-web/PreviewWeb.test.ts b/code/core/src/preview-api/modules/preview-web/PreviewWeb.test.ts index 61fba8bdf44..83a66c52b89 100644 --- a/code/core/src/preview-api/modules/preview-web/PreviewWeb.test.ts +++ b/code/core/src/preview-api/modules/preview-web/PreviewWeb.test.ts @@ -164,7 +164,10 @@ describe('PreviewWeb', () => { const preview = await createAndRenderPreview(); - expect((preview.storyStore as StoryStore)!.userGlobals.get()).toEqual({ a: 'c' }); + // @ts-expect-error Ignore protected property + expect((preview.storyStoreValue as StoryStore)!.userGlobals.get()).toEqual({ + a: 'c', + }); }); it('emits the SET_GLOBALS event', async () => { @@ -208,7 +211,10 @@ describe('PreviewWeb', () => { const preview = await createAndRenderPreview(); - expect((preview.storyStore as StoryStore)?.args.get('component-one--a')).toEqual({ + expect( + // @ts-expect-error Ignore protected property + (preview.storyStoreValue as StoryStore)?.args.get('component-one--a') + ).toEqual({ foo: 'url', one: 1, }); @@ -234,7 +240,10 @@ describe('PreviewWeb', () => { }); await preview.ready(); - expect((preview.storyStore as StoryStore)!.userGlobals.get()).toEqual({ a: 'b' }); + // @ts-expect-error Ignore protected property + expect((preview.storyStoreValue as StoryStore)!.userGlobals.get()).toEqual({ + a: 'b', + }); }); }); @@ -896,7 +905,10 @@ describe('PreviewWeb', () => { emitter.emit(UPDATE_GLOBALS, { globals: { foo: 'bar' } }); - expect((preview.storyStore as StoryStore)!.userGlobals.get()).toEqual({ a: 'b' }); + // @ts-expect-error Ignore protected property + expect((preview.storyStoreValue as StoryStore)!.userGlobals.get()).toEqual({ + a: 'b', + }); }); it('passes globals in context to renderToCanvas', async () => { @@ -973,7 +985,8 @@ describe('PreviewWeb', () => { }); expect( - (preview.storyStore as StoryStore as StoryStore)?.args.get( + // @ts-expect-error Ignore protected property + (preview.storyStoreValue as StoryStore as StoryStore)?.args.get( 'component-one--a' ) ).toEqual({ @@ -1257,7 +1270,8 @@ describe('PreviewWeb', () => { await waitForRender(); mockChannel.emit.mockClear(); - const story = await (preview.storyStore as StoryStore)?.loadStory({ + // @ts-expect-error Ignore protected property + const story = await (preview.storyStoreValue as StoryStore)?.loadStory({ storyId: 'component-one--a', }); preview.renderStoryToElement(story, 'story-element' as any, callbacks, {}); @@ -1297,7 +1311,8 @@ describe('PreviewWeb', () => { await waitForRender(); mockChannel.emit.mockClear(); - const story = await (preview.storyStore as StoryStore)?.loadStory({ + // @ts-expect-error Ignore protected property + const story = await (preview.storyStoreValue as StoryStore)?.loadStory({ storyId: 'component-one--a', }); preview.renderStoryToElement(story, 'story-element' as any, callbacks, { @@ -2288,7 +2303,10 @@ describe('PreviewWeb', () => { updatedArgs: { foo: 'updated' }, }); await waitForRender(); - expect((preview.storyStore as StoryStore)?.args.get('component-one--a')).toEqual({ + expect( + // @ts-expect-error Ignore protected property + (preview.storyStoreValue as StoryStore)?.args.get('component-one--a') + ).toEqual({ foo: 'updated', one: 1, }); @@ -2300,7 +2318,10 @@ describe('PreviewWeb', () => { }); await waitForSetCurrentStory(); await waitForRender(); - expect((preview.storyStore as StoryStore)?.args.get('component-one--a')).toEqual({ + expect( + // @ts-expect-error Ignore protected property + (preview.storyStoreValue as StoryStore)?.args.get('component-one--a') + ).toEqual({ foo: 'updated', one: 1, }); @@ -2312,7 +2333,10 @@ describe('PreviewWeb', () => { }); await waitForSetCurrentStory(); await waitForRender(); - expect((preview.storyStore as StoryStore)?.args.get('component-one--a')).toEqual({ + expect( + // @ts-expect-error Ignore protected property + (preview.storyStoreValue as StoryStore)?.args.get('component-one--a') + ).toEqual({ foo: 'updated', one: 1, }); @@ -2885,7 +2909,10 @@ describe('PreviewWeb', () => { mockFetchResult = { status: 200, json: mockStoryIndex, text: () => 'error text' }; preview.onStoryIndexChanged(); await waitForRender(); - expect((preview.storyStore as StoryStore)?.args.get('component-one--a')).toEqual({ + expect( + // @ts-expect-error Ignore protected property + (preview.storyStoreValue as StoryStore)?.args.get('component-one--a') + ).toEqual({ foo: 'url', one: 1, }); @@ -3334,7 +3361,10 @@ describe('PreviewWeb', () => { }); await waitForSetCurrentStory(); await waitForRender(); - expect((preview.storyStore as StoryStore)?.args.get('component-one--a')).toEqual({ + expect( + // @ts-expect-error Ignore protected property + (preview.storyStoreValue as StoryStore)?.args.get('component-one--a') + ).toEqual({ foo: 'updated', one: 1, }); @@ -3353,7 +3383,10 @@ describe('PreviewWeb', () => { }); await waitForSetCurrentStory(); await waitForRender(); - expect((preview.storyStore as StoryStore)?.args.get('component-one--a')).toEqual({ + expect( + // @ts-expect-error Ignore protected property + (preview.storyStoreValue as StoryStore)?.args.get('component-one--a') + ).toEqual({ foo: 'updated', bar: 'edited', one: 1, @@ -3524,7 +3557,10 @@ describe('PreviewWeb', () => { preview.onGetProjectAnnotationsChanged({ getProjectAnnotations }); await waitForRender(); - expect((preview.storyStore as StoryStore)!.userGlobals.get()).toEqual({ a: 'c' }); + // @ts-expect-error Ignore protected property + expect((preview.storyStoreValue as StoryStore)!.userGlobals.get()).toEqual({ + a: 'c', + }); }); }); @@ -3573,7 +3609,8 @@ describe('PreviewWeb', () => { preview.onGetProjectAnnotationsChanged({ getProjectAnnotations: newGetProjectAnnotations }); await waitForRender(); - expect((preview.storyStore as StoryStore)!.userGlobals.get()).toEqual({ + // @ts-expect-error Ignore protected property + expect((preview.storyStoreValue as StoryStore)!.userGlobals.get()).toEqual({ a: 'edited', }); }); @@ -3601,7 +3638,10 @@ describe('PreviewWeb', () => { preview.onGetProjectAnnotationsChanged({ getProjectAnnotations: newGetProjectAnnotations }); await waitForRender(); - expect((preview.storyStore as StoryStore)?.args.get('component-one--a')).toEqual({ + expect( + // @ts-expect-error Ignore protected property + (preview.storyStoreValue as StoryStore)?.args.get('component-one--a') + ).toEqual({ foo: 'a', one: 1, global: 'added', @@ -3729,7 +3769,8 @@ describe('PreviewWeb', () => { componentOneExports.b.play.mockImplementationOnce(async () => gate); // @ts-expect-error (not strict) preview.renderStoryToElement( - await (preview.storyStore as StoryStore)?.loadStory({ + // @ts-expect-error Ignore protected property + await (preview.storyStoreValue as StoryStore)?.loadStory({ storyId: 'component-one--b', }), {} as any, diff --git a/code/lib/blocks/src/components/Preview.stories.tsx b/code/lib/blocks/src/components/Preview.stories.tsx index 61ee6577db1..4f9fab21601 100644 --- a/code/lib/blocks/src/components/Preview.stories.tsx +++ b/code/lib/blocks/src/components/Preview.stories.tsx @@ -30,70 +30,70 @@ export const Loading = () => ; export const CodeCollapsed = () => ( - + ); export const CodeExpanded = () => ( - + ); export const CodeError = () => ( - + ); export const Single = () => ( - + ); export const Row = () => ( - - - - - - - + + + + + + + ); export const Column = () => ( - - - + + + ); export const GridWith3Columns = () => ( - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + ); @@ -241,10 +241,7 @@ export const WithCenteredMulti = ( ); -export const WithAdditionalActions = ( - args: any, - { loaded: { docsContext } }: { loaded: { docsContext: DocsContextProps } } -) => ( +export const WithAdditionalActions = () => ( - + ); diff --git a/code/lib/cli-storybook/src/automigrate/fixes/vite-config-file.ts b/code/lib/cli-storybook/src/automigrate/fixes/vite-config-file.ts index 4d1389c41e7..ebfad7bc565 100644 --- a/code/lib/cli-storybook/src/automigrate/fixes/vite-config-file.ts +++ b/code/lib/cli-storybook/src/automigrate/fixes/vite-config-file.ts @@ -1,7 +1,6 @@ import { join } from 'node:path'; -import { frameworkToRenderer } from 'storybook/internal/cli'; -import { frameworkPackages } from 'storybook/internal/common'; +import { frameworkPackages, frameworkToRenderer } from 'storybook/internal/common'; import findUp from 'find-up'; import { dedent } from 'ts-dedent'; diff --git a/code/lib/cli-storybook/src/automigrate/helpers/mainConfigFile.ts b/code/lib/cli-storybook/src/automigrate/helpers/mainConfigFile.ts index 6a93538da49..11da55c5551 100644 --- a/code/lib/cli-storybook/src/automigrate/helpers/mainConfigFile.ts +++ b/code/lib/cli-storybook/src/automigrate/helpers/mainConfigFile.ts @@ -1,6 +1,5 @@ import { normalize } from 'node:path'; -import { frameworkToRenderer } from 'storybook/internal/cli'; import { builderPackages, extractProperFrameworkName, @@ -10,7 +9,7 @@ import { rendererPackages, } from 'storybook/internal/common'; import type { JsPackageManager } from 'storybook/internal/common'; -import { getCoercedStorybookVersion } from 'storybook/internal/common'; +import { frameworkToRenderer, getCoercedStorybookVersion } from 'storybook/internal/common'; import type { ConfigFile } from 'storybook/internal/csf-tools'; import { readConfig, writeConfig as writeConfigFile } from 'storybook/internal/csf-tools'; import type { StorybookConfigRaw } from 'storybook/internal/types'; From 77e6047006ee997a1c00c8b39d749b08150dc621 Mon Sep 17 00:00:00 2001 From: Valentin Palkovic Date: Wed, 26 Mar 2025 14:41:28 +0100 Subject: [PATCH 30/37] Fix tests --- code/core/src/core-server/build-index.test.ts | 13 +++++++++++ .../modules/store/StoryStore.test.ts | 2 +- .../modules/store/csf/composeConfigs.test.ts | 22 +++++-------------- code/core/template/stories/globals.stories.ts | 6 ++--- code/core/template/stories/preview.ts | 4 +--- .../portable-stories-factory.test.tsx | 4 ++-- .../__test__/portable-stories-legacy.test.tsx | 4 +--- .../src/__test__/portable-stories.test.tsx | 4 +--- .../composeStories/portable-stories.test.ts | 4 +--- 9 files changed, 29 insertions(+), 34 deletions(-) diff --git a/code/core/src/core-server/build-index.test.ts b/code/core/src/core-server/build-index.test.ts index e467a4f86a8..a1769a1eb7a 100644 --- a/code/core/src/core-server/build-index.test.ts +++ b/code/core/src/core-server/build-index.test.ts @@ -10,6 +10,19 @@ describe('buildIndex', () => { expect(index).toMatchInlineSnapshot(` { "entries": { + "my-component-a--docs": { + "id": "my-component-a--docs", + "importPath": "./core/src/core-server/utils/__mockdata__/docs-id-generation/A.stories.jsx", + "name": "Docs", + "storiesImports": [], + "tags": [ + "dev", + "test", + "autodocs", + ], + "title": "A", + "type": "docs", + }, "my-component-a--story-one": { "componentPath": undefined, "id": "my-component-a--story-one", diff --git a/code/core/src/preview-api/modules/store/StoryStore.test.ts b/code/core/src/preview-api/modules/store/StoryStore.test.ts index c25c419155c..95fb773e189 100644 --- a/code/core/src/preview-api/modules/store/StoryStore.test.ts +++ b/code/core/src/preview-api/modules/store/StoryStore.test.ts @@ -45,7 +45,7 @@ const importFn = vi.fn(async (path) => { const projectAnnotations: ProjectAnnotations = composeConfigs([ { - globals: { a: 'b' }, + initialGlobals: { a: 'b' }, globalTypes: { a: { type: 'string' } }, argTypes: { a: { type: 'string' } }, render: vi.fn(), diff --git a/code/core/src/preview-api/modules/store/csf/composeConfigs.test.ts b/code/core/src/preview-api/modules/store/csf/composeConfigs.test.ts index d1539c4791e..413e9594633 100644 --- a/code/core/src/preview-api/modules/store/csf/composeConfigs.test.ts +++ b/code/core/src/preview-api/modules/store/csf/composeConfigs.test.ts @@ -19,7 +19,6 @@ describe('composeConfigs', () => { argsEnhancers: [], argTypes: {}, argTypesEnhancers: [], - globals: {}, initialGlobals: {}, globalTypes: {}, loaders: [], @@ -48,7 +47,6 @@ describe('composeConfigs', () => { argsEnhancers: [], argTypes: {}, argTypesEnhancers: [], - globals: {}, initialGlobals: {}, globalTypes: {}, loaders: [], @@ -81,7 +79,6 @@ describe('composeConfigs', () => { argsEnhancers: [], argTypes: {}, argTypesEnhancers: [], - globals: {}, initialGlobals: {}, globalTypes: {}, loaders: [], @@ -100,7 +97,7 @@ describe('composeConfigs', () => { default: { args: { x: '1', y: '1', obj: { a: '1', b: '1' } }, argTypes: { x: '1', y: '1', obj: { a: '1', b: '1' } }, - globals: { x: '1', y: '1', obj: { a: '1', b: '1' } }, + initialGlobals: { x: '1', y: '1', obj: { a: '1', b: '1' } }, globalTypes: { x: '1', y: '1', obj: { a: '1', b: '1' } }, }, }, @@ -108,7 +105,7 @@ describe('composeConfigs', () => { default: { args: { x: '2', z: '2', obj: { a: '2', c: '2' } }, argTypes: { x: '2', z: '2', obj: { a: '2', c: '2' } }, - globals: { x: '2', z: '2', obj: { a: '2', c: '2' } }, + initialGlobals: { x: '2', z: '2', obj: { a: '2', c: '2' } }, globalTypes: { x: '2', z: '2', obj: { a: '2', c: '2' } }, }, }, @@ -120,8 +117,7 @@ describe('composeConfigs', () => { argsEnhancers: [], argTypes: { x: '2', y: '1', z: '2', obj: { a: '2', c: '2' } }, argTypesEnhancers: [], - globals: { x: '2', y: '1', z: '2', obj: { a: '2', c: '2' } }, - initialGlobals: {}, + initialGlobals: { x: '2', y: '1', z: '2', obj: { a: '2', c: '2' } }, globalTypes: { x: '2', y: '1', z: '2', obj: { a: '2', c: '2' } }, loaders: [], beforeAll: expect.any(Function), @@ -140,14 +136,14 @@ describe('composeConfigs', () => { default: { args: { x: '1', y: '1', obj: { a: '1', b: '1' } }, argTypes: { x: '1', y: '1', obj: { a: '1', b: '1' } }, - globals: { x: '1', y: '1', obj: { a: '1', b: '1' } }, + initialGlobals: { x: '1', y: '1', obj: { a: '1', b: '1' } }, globalTypes: { x: '1', y: '1', obj: { a: '1', b: '1' } }, }, }, { args: { x: '2', z: '2', obj: { a: '2', c: '2' } }, argTypes: { x: '2', z: '2', obj: { a: '2', c: '2' } }, - globals: { x: '2', z: '2', obj: { a: '2', c: '2' } }, + initialGlobals: { x: '2', z: '2', obj: { a: '2', c: '2' } }, }, { default: { @@ -162,8 +158,7 @@ describe('composeConfigs', () => { argsEnhancers: [], argTypes: { x: '2', y: '1', z: '2', obj: { a: '2', c: '2' } }, argTypesEnhancers: [], - globals: { x: '2', y: '1', z: '2', obj: { a: '2', c: '2' } }, - initialGlobals: {}, + initialGlobals: { x: '2', y: '1', z: '2', obj: { a: '2', c: '2' } }, globalTypes: { x: '2', y: '1', z: '2', obj: { a: '2', c: '2' } }, loaders: [], beforeAll: expect.any(Function), @@ -195,7 +190,6 @@ describe('composeConfigs', () => { argsEnhancers: ['1', '2', '3', '4'], argTypes: {}, argTypesEnhancers: ['1', '2', '3', '4'], - globals: {}, initialGlobals: {}, globalTypes: {}, loaders: ['1', '2', '3', '4'], @@ -228,7 +222,6 @@ describe('composeConfigs', () => { argsEnhancers: ['1', '2', '3'], argTypes: {}, argTypesEnhancers: ['1', '2', '3'], - globals: {}, initialGlobals: {}, globalTypes: {}, loaders: ['1', '2', '3'], @@ -257,7 +250,6 @@ describe('composeConfigs', () => { argsEnhancers: [], argTypes: {}, argTypesEnhancers: [], - globals: {}, initialGlobals: {}, globalTypes: {}, loaders: [], @@ -287,7 +279,6 @@ describe('composeConfigs', () => { { a: '2', secondPass: true }, { a: '4', secondPass: true }, ], - globals: {}, initialGlobals: {}, globalTypes: {}, loaders: [], @@ -320,7 +311,6 @@ describe('composeConfigs', () => { argsEnhancers: [], argTypes: {}, argTypesEnhancers: [], - globals: {}, initialGlobals: {}, globalTypes: {}, loaders: [], diff --git a/code/core/template/stories/globals.stories.ts b/code/core/template/stories/globals.stories.ts index cf6be5d0d1b..95197f3b814 100644 --- a/code/core/template/stories/globals.stories.ts +++ b/code/core/template/stories/globals.stories.ts @@ -21,7 +21,7 @@ export const Inheritance = { play: async ({ canvasElement }: PlayFunctionContext) => { await expect(JSON.parse(within(canvasElement).getByTestId('pre').innerText)).toMatchObject({ foo: 'fooValue', - bar: 'barDefaultValue', + bar: 'barValue', baz: 'bazComponentValue', }); }, @@ -63,7 +63,7 @@ export const Overrides1 = { play: async ({ canvasElement }: PlayFunctionContext) => { await expect(JSON.parse(within(canvasElement).getByTestId('pre').innerText)).toMatchObject({ foo: 'fooOverridden1', - bar: 'barDefaultValue', + bar: 'barValue', baz: 'bazOverridden1', }); }, @@ -82,7 +82,7 @@ export const Overrides2 = { play: async ({ canvasElement }: PlayFunctionContext) => { await expect(JSON.parse(within(canvasElement).getByTestId('pre').innerText)).toMatchObject({ foo: 'fooOverridden2', - bar: 'barDefaultValue', + bar: 'barValue', baz: 'bazOverridden2', }); }, diff --git a/code/core/template/stories/preview.ts b/code/core/template/stories/preview.ts index 1443b4c6c7c..9cecaf77c5f 100644 --- a/code/core/template/stories/preview.ts +++ b/code/core/template/stories/preview.ts @@ -49,6 +49,7 @@ export const decorators = [testProjectDecorator]; export const initialGlobals = { foo: 'fooValue', + bar: 'barValue', baz: 'bazValue', sb_theme: 'light', @@ -61,9 +62,6 @@ export const initialGlobals = { }; export const globalTypes = { - foo: { defaultValue: 'fooDefaultValue' }, - bar: { defaultValue: 'barDefaultValue' }, - sb_theme: { name: 'Theme', description: 'Global theme for components', diff --git a/code/renderers/react/src/__test__/portable-stories-factory.test.tsx b/code/renderers/react/src/__test__/portable-stories-factory.test.tsx index fae74680643..072bbbbaaaa 100644 --- a/code/renderers/react/src/__test__/portable-stories-factory.test.tsx +++ b/code/renderers/react/src/__test__/portable-stories-factory.test.tsx @@ -99,8 +99,8 @@ describe('projectAnnotations', () => { setProjectAnnotations([ { parameters: { injected: true }, - globalTypes: { - locale: { defaultValue: 'en' }, + initialGlobals: { + locale: 'en', }, }, ]); diff --git a/code/renderers/react/src/__test__/portable-stories-legacy.test.tsx b/code/renderers/react/src/__test__/portable-stories-legacy.test.tsx index 2537ac0dedd..39d12b35ac1 100644 --- a/code/renderers/react/src/__test__/portable-stories-legacy.test.tsx +++ b/code/renderers/react/src/__test__/portable-stories-legacy.test.tsx @@ -70,9 +70,7 @@ describe('Legacy Portable Stories API', () => { setProjectAnnotations([ { parameters: { injected: true }, - globalTypes: { - locale: { defaultValue: 'en' }, - }, + initialGlobals: { locale: 'en' }, }, ]); const WithEnglishText = composeStory(stories.CSF2StoryWithLocale, stories.default); diff --git a/code/renderers/react/src/__test__/portable-stories.test.tsx b/code/renderers/react/src/__test__/portable-stories.test.tsx index 704dfb21ec3..0ea0a50a378 100644 --- a/code/renderers/react/src/__test__/portable-stories.test.tsx +++ b/code/renderers/react/src/__test__/portable-stories.test.tsx @@ -90,9 +90,7 @@ describe('projectAnnotations', () => { setProjectAnnotations([ { parameters: { injected: true }, - globalTypes: { - locale: { defaultValue: 'en' }, - }, + initialGlobals: { locale: 'en' }, }, ]); const WithEnglishText = composeStory(ButtonStories.CSF2StoryWithLocale, ButtonStories.default); diff --git a/code/renderers/vue3/src/__tests__/composeStories/portable-stories.test.ts b/code/renderers/vue3/src/__tests__/composeStories/portable-stories.test.ts index 9c8b20cab2e..f6b21b7db14 100644 --- a/code/renderers/vue3/src/__tests__/composeStories/portable-stories.test.ts +++ b/code/renderers/vue3/src/__tests__/composeStories/portable-stories.test.ts @@ -66,9 +66,7 @@ describe('projectAnnotations', () => { setProjectAnnotations([ { parameters: { injected: true }, - globalTypes: { - locale: { defaultValue: 'en' }, - }, + initialGlobals: { locale: 'en' }, }, ]); const WithEnglishText = composeStory(stories.CSF2StoryWithLocale, stories.default); From bf0c48765df92d6431424eadbe1def3c69feb932 Mon Sep 17 00:00:00 2001 From: Valentin Palkovic Date: Wed, 26 Mar 2025 18:55:09 +0100 Subject: [PATCH 31/37] Remove deprecated manual parameter from A11yParameters and related tests; update A11yContext to reflect changes in manual mode handling. --- MIGRATION.md | 37 +++++++++++++++ .../a11y/src/components/A11yContext.test.tsx | 47 ------------------- .../a11y/src/components/A11yContext.tsx | 10 +--- code/addons/a11y/src/params.ts | 2 - code/addons/a11y/src/preview.tsx | 1 - 5 files changed, 39 insertions(+), 58 deletions(-) diff --git a/MIGRATION.md b/MIGRATION.md index 8da86425c6d..7a00105b916 100644 --- a/MIGRATION.md +++ b/MIGRATION.md @@ -1,6 +1,7 @@

Migration

- [From version 8.x to 9.0.0](#from-version-8x-to-900) + - [A11y addon: Removed deprecated manual parameter](#a11y-addon-removed-deprecated-manual-parameter) - [Button Component API Changes](#button-component-api-changes) - [Documentation Generation Changes](#documentation-generation-changes) - [Global State Management](#global-state-management) @@ -421,6 +422,42 @@ ## From version 8.x to 9.0.0 +### A11y addon: Removed deprecated manual parameter + +The deprecated `manual` parameter from the A11y addon's parameters has been removed. Instead, use the `globals.a11y.manual` setting to control manual mode. For example: + +```js +// Old way (no longer works) +export const MyStory = { + parameters: { + a11y: { + manual: true + } + } +}; + +// New way +export const MyStory = { + parameters: { + a11y: { + // other a11y parameters + } + } + globals: { + a11y: { + manual: true + } + } +}; + +// To enable manual mode globally, use .storybook/preview.js: +export const initialGlobals = { + a11y: { + manual: true + } +}; +``` + ### Button Component API Changes The Button component has been updated to use a more modern props API. The following props have been removed: diff --git a/code/addons/a11y/src/components/A11yContext.test.tsx b/code/addons/a11y/src/components/A11yContext.test.tsx index bfb96af0edf..b033a974320 100644 --- a/code/addons/a11y/src/components/A11yContext.test.tsx +++ b/code/addons/a11y/src/components/A11yContext.test.tsx @@ -151,24 +151,6 @@ describe('A11yContext', () => { ); }); - it('should set discrepancy to cliFailedButModeManual when in manual mode', () => { - mockedApi.useParameter.mockReturnValue({ manual: true }); - mockedApi.experimental_useStatusStore.mockReturnValue('status-value:error'); - - const Component = () => { - const { discrepancy } = useA11yContext(); - return
{discrepancy}
; - }; - - const { getByTestId } = render( - - - - ); - - expect(getByTestId('discrepancy').textContent).toBe('cliFailedButModeManual'); - }); - it('should set discrepancy to cliFailedButModeManual when in manual mode (set via globals)', () => { mockedApi.useGlobals.mockReturnValue([{ a11y: { manual: true } }] as any); mockedApi.experimental_useStatusStore.mockReturnValue('status-value:error'); @@ -249,35 +231,6 @@ describe('A11yContext', () => { expect(queryByTestId('status')).toHaveTextContent('running'); }); - it('should handle STORY_RENDER_PHASE_CHANGED event correctly when in manual mode', () => { - mockedApi.useParameter.mockReturnValue({ manual: true }); - - const emit = vi.fn(); - mockedApi.useChannel.mockReturnValue(emit); - - const Component = () => { - const { status } = useA11yContext(); - return
{status}
; - }; - - const { queryByTestId } = render( - - - - ); - - expect(queryByTestId('status')).toHaveTextContent('manual'); - - const useChannelArgs = mockedApi.useChannel.mock.calls[0][0]; - const storyRenderPhaseChangedPayload = { - newPhase: 'loading', - }; - - act(() => useChannelArgs[STORY_RENDER_PHASE_CHANGED](storyRenderPhaseChangedPayload)); - - expect(queryByTestId('status')).toHaveTextContent('manual'); - }); - it('should handle STORY_RENDER_PHASE_CHANGED event correctly when in manual mode (set via globals)', () => { mockedApi.useGlobals.mockReturnValue([{ a11y: { manual: true } }] as any); diff --git a/code/addons/a11y/src/components/A11yContext.tsx b/code/addons/a11y/src/components/A11yContext.tsx index bd0c52463ff..42dee3f0ff6 100644 --- a/code/addons/a11y/src/components/A11yContext.tsx +++ b/code/addons/a11y/src/components/A11yContext.tsx @@ -80,20 +80,14 @@ const defaultResult = { type Status = 'initial' | 'manual' | 'running' | 'error' | 'ran' | 'ready'; export const A11yContextProvider: FC = (props) => { - const parameters = useParameter('a11y', { - manual: false, - }); + const parameters = useParameter('a11y', {}); const [globals] = useGlobals() ?? []; const getInitialStatus = useCallback((manual = false) => (manual ? 'manual' : 'initial'), []); - const manual = useMemo( - () => globals?.a11y?.manual ?? parameters.manual ?? false, - [globals?.a11y?.manual, parameters.manual] - ); + const manual = useMemo(() => globals?.a11y?.manual ?? false, [globals?.a11y?.manual]); - const api = useStorybookApi(); const [results, setResults] = useAddonState(ADDON_ID, defaultResult); const [tab, setTab] = useState(0); const [error, setError] = React.useState(undefined); diff --git a/code/addons/a11y/src/params.ts b/code/addons/a11y/src/params.ts index a5776a5564b..183fbc38195 100644 --- a/code/addons/a11y/src/params.ts +++ b/code/addons/a11y/src/params.ts @@ -12,8 +12,6 @@ export interface A11yParameters { element?: ElementContext; config?: Spec; options?: RunOptions; - /** @deprecated Use globals.a11y.manual instead */ - manual?: boolean; disable?: boolean; test?: A11yTest; } diff --git a/code/addons/a11y/src/preview.tsx b/code/addons/a11y/src/preview.tsx index 4a0704ed3eb..f289885b728 100644 --- a/code/addons/a11y/src/preview.tsx +++ b/code/addons/a11y/src/preview.tsx @@ -18,7 +18,6 @@ export const experimental_afterEach: AfterEach = async ({ const a11yGlobals = globals.a11y; const shouldRunEnvironmentIndependent = - a11yParameter?.manual !== true && a11yParameter?.disable !== true && a11yParameter?.test !== 'off' && a11yGlobals?.manual !== true; From 2a181d8018d379000dffa45b732dbc14e9945834 Mon Sep 17 00:00:00 2001 From: Valentin Palkovic Date: Wed, 26 Mar 2025 19:10:15 +0100 Subject: [PATCH 32/37] Fix docs usage in Storybook UI --- code/.storybook/preview.tsx | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/code/.storybook/preview.tsx b/code/.storybook/preview.tsx index 232b9a4cff2..4daa53bb171 100644 --- a/code/.storybook/preview.tsx +++ b/code/.storybook/preview.tsx @@ -12,6 +12,7 @@ import type { Decorator, Loader, ReactRenderer } from '@storybook/react-vite'; import { definePreview } from '@storybook/react-vite'; import addonA11y from '@storybook/addon-a11y'; +import addonDocs from '@storybook/addon-docs'; import addonEssentials from '@storybook/addon-essentials'; import addonTest from '@storybook/addon-test'; import addonThemes from '@storybook/addon-themes'; @@ -372,7 +373,14 @@ const parameters = { }; export default definePreview({ - addons: [addonThemes(), addonEssentials(), addonA11y(), addonTest(), templatePreview], + addons: [ + addonDocs(), + addonThemes(), + addonEssentials(), + addonA11y(), + addonTest(), + templatePreview, + ], decorators, loaders, tags: ['test', 'vitest'], From 90b543cff54c49fe222c45dd22fafed4a38fbab8 Mon Sep 17 00:00:00 2001 From: Valentin Palkovic Date: Wed, 26 Mar 2025 19:42:47 +0100 Subject: [PATCH 33/37] Remove obsolete test --- code/addons/a11y/src/preview.test.tsx | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/code/addons/a11y/src/preview.test.tsx b/code/addons/a11y/src/preview.test.tsx index 829749a8774..f665dac7f65 100644 --- a/code/addons/a11y/src/preview.test.tsx +++ b/code/addons/a11y/src/preview.test.tsx @@ -183,21 +183,6 @@ describe('afterEach', () => { }); }); - it('should not run accessibility checks when manual is true', async () => { - const context = createContext({ - parameters: { - a11y: { - manual: true, - }, - }, - }); - - await experimental_afterEach(context); - - expect(mockedRun).not.toHaveBeenCalled(); - expect(context.reporting.addReport).not.toHaveBeenCalled(); - }); - it('should not run accessibility checks when disable is true', async () => { const context = createContext({ parameters: { From 530731db1d7fac467eb1ec2c76304e10ee3ed567 Mon Sep 17 00:00:00 2001 From: Valentin Palkovic Date: Wed, 26 Mar 2025 20:08:39 +0100 Subject: [PATCH 34/37] Revert "Refactor StoryStore access in Storybook preview to use the new StoryStore instance and remove deprecated proxy method" This reverts commit ae7e69e65682a3cbafbd166808acc9945b0fce9b. --- code/.storybook/preview.tsx | 13 +++++------- .../modules/preview-web/Preview.tsx | 21 +++++++++++++++++++ 2 files changed, 26 insertions(+), 8 deletions(-) diff --git a/code/.storybook/preview.tsx b/code/.storybook/preview.tsx index 4daa53bb171..805ea0f6e55 100644 --- a/code/.storybook/preview.tsx +++ b/code/.storybook/preview.tsx @@ -18,7 +18,7 @@ import addonTest from '@storybook/addon-test'; import addonThemes from '@storybook/addon-themes'; import { DocsContext as DocsContextProps, useArgs } from 'storybook/preview-api'; -import type { PreviewWeb, StoryStore } from 'storybook/preview-api'; +import type { PreviewWeb } from 'storybook/preview-api'; import { Global, ThemeProvider, @@ -147,12 +147,9 @@ const loaders = [ // eslint-disable-next-line no-underscore-dangle const preview = (window as any).__STORYBOOK_PREVIEW__ as PreviewWeb | undefined; const channel = (window as any).__STORYBOOK_ADDONS_CHANNEL__ as Channel | undefined; - const storyStore = (window as any).__STORYBOOK_STORY_STORE__ as - | StoryStore - | undefined; // __STORYBOOK_PREVIEW__ and __STORYBOOK_ADDONS_CHANNEL__ is set in the PreviewWeb constructor // which isn't loaded in portable stories/vitest - if (!relativeCsfPaths || !preview || !channel || !storyStore) { + if (!relativeCsfPaths || !preview || !channel) { return {}; } const csfFiles = await Promise.all( @@ -161,7 +158,7 @@ const loaders = [ /^..\//, '' )}.tsx`; - const entry = storyStore.storyIndex?.importPathToEntry(projectRelativePath); + const entry = preview.storyStore.storyIndex?.importPathToEntry(projectRelativePath); if (!entry) { throw new Error( @@ -169,12 +166,12 @@ const loaders = [ ); } - return storyStore.loadCSFFileByStoryId(entry.id); + return preview.storyStore.loadCSFFileByStoryId(entry.id); }) ); const docsContext = new DocsContextProps( channel, - storyStore, + preview.storyStore, preview.renderStoryToElement.bind(preview), csfFiles ); diff --git a/code/core/src/preview-api/modules/preview-web/Preview.tsx b/code/core/src/preview-api/modules/preview-web/Preview.tsx index b31152c1bda..d9ebef40736 100644 --- a/code/core/src/preview-api/modules/preview-web/Preview.tsx +++ b/code/core/src/preview-api/modules/preview-web/Preview.tsx @@ -98,6 +98,27 @@ export class Preview { } } + // Create a proxy object for `__STORYBOOK_STORY_STORE__` and `__STORYBOOK_PREVIEW__.storyStore` + // That proxies through to the store once ready, and errors beforehand. This means we can set + // `__STORYBOOK_STORY_STORE__ = __STORYBOOK_PREVIEW__.storyStore` without having to wait, and + // similarly integrators can access the `storyStore` on the preview at any time, although + // it is considered deprecated and we will no longer allow access in 9.0 + get storyStore() { + return new Proxy( + {}, + { + get: (_, method) => { + if (this.storyStoreValue) { + deprecate('Accessing the Story Store is deprecated and will be removed in 9.0'); + return this.storyStoreValue[method as keyof StoryStore]; + } + + throw new StoryStoreAccessedBeforeInitializationError(); + }, + } + ) as StoryStore; + } + // INITIALIZATION protected async initialize() { this.setupListeners(); From a93bbc358ea5a439a85afe81fb8e288b66fdb0f5 Mon Sep 17 00:00:00 2001 From: Valentin Palkovic Date: Thu, 27 Mar 2025 11:59:23 +0100 Subject: [PATCH 35/37] Remove unused manualParameter from A11YPanel and update documentation to reflect changes in manual mode configuration. --- code/addons/a11y/src/components/A11YPanel.tsx | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/code/addons/a11y/src/components/A11YPanel.tsx b/code/addons/a11y/src/components/A11YPanel.tsx index 50e32dc5f43..0a86175581e 100644 --- a/code/addons/a11y/src/components/A11YPanel.tsx +++ b/code/addons/a11y/src/components/A11YPanel.tsx @@ -62,7 +62,6 @@ const Count = styled(Badge)({ }); export const A11YPanel: React.FC = () => { - const { manual: manualParameter } = useParameter(PARAM_KEY, {} as any); const { results, status, @@ -167,8 +166,7 @@ export const A11YPanel: React.FC = () => { Run accessibility scan

- Update {manualParameter ? 'parameters' : 'globals'}.a11y.manual to - disable manual mode. + Update globals.a11y.manual to disable manual mode.

)} From 8323d2c40595034645d10a92568548a06723d208 Mon Sep 17 00:00:00 2001 From: Valentin Palkovic Date: Fri, 28 Mar 2025 11:15:51 +0100 Subject: [PATCH 36/37] Update code/core/src/cli/dirs.ts Co-authored-by: Norbert de Langen --- code/core/src/cli/dirs.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/code/core/src/cli/dirs.ts b/code/core/src/cli/dirs.ts index 16d32e4a3e3..8d6f2af89e9 100644 --- a/code/core/src/cli/dirs.ts +++ b/code/core/src/cli/dirs.ts @@ -2,8 +2,7 @@ import { dirname, join } from 'node:path'; import { temporaryDirectory, versions } from 'storybook/internal/common'; import type { JsPackageManager } from 'storybook/internal/common'; -import type { SupportedFrameworks } from 'storybook/internal/types'; -import type { SupportedRenderers } from 'storybook/internal/types'; +import type { SupportedFrameworks, SupportedRenderers } from 'storybook/internal/types'; import downloadTarballDefault from '@ndelangen/get-tarball'; import getNpmTarballUrlDefault from 'get-npm-tarball-url'; From adf2703a3d24f9240fd90846acd8eb9acccd6147 Mon Sep 17 00:00:00 2001 From: Valentin Palkovic Date: Fri, 28 Mar 2025 11:18:00 +0100 Subject: [PATCH 37/37] Refactor Button component to remove unnecessary local variables for variant and size, directly using props instead. --- code/core/src/components/components/Button/Button.tsx | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/code/core/src/components/components/Button/Button.tsx b/code/core/src/components/components/Button/Button.tsx index 6aecce3905d..30e8c0186b0 100644 --- a/code/core/src/components/components/Button/Button.tsx +++ b/code/core/src/components/components/Button/Button.tsx @@ -36,8 +36,6 @@ export const Button = forwardRef( if (asChild) { Comp = Slot; } - const localVariant = variant; - const localSize = size; const [isAnimating, setIsAnimating] = useState(false); @@ -65,8 +63,8 @@ export const Button = forwardRef(