diff --git a/code/addons/a11y/package.json b/code/addons/a11y/package.json index f4e3d47c5779..0c353f55584a 100644 --- a/code/addons/a11y/package.json +++ b/code/addons/a11y/package.json @@ -67,9 +67,9 @@ "@storybook/icons": "^1.6.0", "@testing-library/react": "^14.0.0", "execa": "^9.5.2", - "react": "^18.2.0", - "react-dom": "^18.2.0", - "react-resize-detector": "^7.1.2", + "react": "^19.1.1", + "react-dom": "^19.1.1", + "react-resize-detector": "^12.3.0", "typescript": "^5.8.3", "vitest-axe": "^0.1.0" }, @@ -79,7 +79,7 @@ "publishConfig": { "access": "public" }, - "gitHead": "a8e7fd8a655c69780bc20b9749d2699e45beae16", + "gitHead": "a8e7fd8a655c69780bc20b9749d2699e45beae18", "storybook": { "displayName": "Accessibility", "icon": "https://user-images.githubusercontent.com/263385/101991665-47042f80-3c7c-11eb-8f00-64b5a18f498a.png", diff --git a/code/addons/docs/package.json b/code/addons/docs/package.json index 824d71c0b279..3f4514b222e7 100644 --- a/code/addons/docs/package.json +++ b/code/addons/docs/package.json @@ -102,9 +102,9 @@ "markdown-to-jsx": "^7.7.2", "memoizerific": "^1.11.3", "polished": "^4.2.2", - "react": "^18.2.0", + "react": "^19.1.1", "react-colorful": "^5.1.2", - "react-dom": "^18.2.0", + "react-dom": "^19.1.1", "rehype-external-links": "^3.0.0", "rehype-slug": "^6.0.0", "telejson": "8.0.0", @@ -118,7 +118,7 @@ "publishConfig": { "access": "public" }, - "gitHead": "a8e7fd8a655c69780bc20b9749d2699e45beae16", + "gitHead": "a8e7fd8a655c69780bc20b9749d2699e45beae18", "storybook": { "displayName": "Docs", "icon": "https://user-images.githubusercontent.com/263385/101991672-48355c80-3c7c-11eb-82d9-95fa12438f64.png", diff --git a/code/addons/docs/src/blocks/blocks/external/ExternalDocs.tsx b/code/addons/docs/src/blocks/blocks/external/ExternalDocs.tsx index 0e8f4cab2f7e..8a3d34f0f6cd 100644 --- a/code/addons/docs/src/blocks/blocks/external/ExternalDocs.tsx +++ b/code/addons/docs/src/blocks/blocks/external/ExternalDocs.tsx @@ -15,7 +15,7 @@ export type ExternalDocsProps = { function usePreview( projectAnnotations: ProjectAnnotations ) { - const previewRef = useRef>(); + const previewRef = useRef | null>(null); if (!previewRef.current) { previewRef.current = new ExternalPreview(projectAnnotations); diff --git a/code/addons/docs/src/blocks/components/ArgsTable/TabbedArgsTable.tsx b/code/addons/docs/src/blocks/components/ArgsTable/TabbedArgsTable.tsx index 0986dab679ed..8222d2e5b6ba 100644 --- a/code/addons/docs/src/blocks/components/ArgsTable/TabbedArgsTable.tsx +++ b/code/addons/docs/src/blocks/components/ArgsTable/TabbedArgsTable.tsx @@ -1,4 +1,4 @@ -import type { FC } from 'react'; +import type { FC, JSX } from 'react'; import React from 'react'; import { TabsState } from 'storybook/internal/components'; diff --git a/code/addons/docs/src/blocks/components/Preview.tsx b/code/addons/docs/src/blocks/components/Preview.tsx index b43dd30519a3..5c608c9fe7d3 100644 --- a/code/addons/docs/src/blocks/components/Preview.tsx +++ b/code/addons/docs/src/blocks/components/Preview.tsx @@ -226,7 +226,7 @@ export const Preview: FC = ({ e.preventDefault(); if (additionalActionItems.filter((item) => item.title === 'Copied').length === 0) { - copyToClipboard(source?.props.code ?? '').then(() => { + copyToClipboard((source?.props as { code?: string })?.code ?? '').then(() => { setAdditionalActionItems([ ...additionalActionItems, { diff --git a/code/addons/docs/src/blocks/components/Story.tsx b/code/addons/docs/src/blocks/components/Story.tsx index 5af081fce655..dceb8a101e82 100644 --- a/code/addons/docs/src/blocks/components/Story.tsx +++ b/code/addons/docs/src/blocks/components/Story.tsx @@ -38,7 +38,7 @@ export const storyBlockIdFromId = ({ story, primary }: StoryProps) => `story--${story.id}${primary ? '--primary' : ''}`; const InlineStory: FunctionComponent = (props) => { - const storyRef = useRef(); + const storyRef = useRef(null); const [showLoader, setShowLoader] = useState(true); const [error, setError] = useState(); diff --git a/code/addons/docs/src/blocks/controls/Date.tsx b/code/addons/docs/src/blocks/controls/Date.tsx index 442d3af9d7c4..7746c806ee7c 100644 --- a/code/addons/docs/src/blocks/controls/Date.tsx +++ b/code/addons/docs/src/blocks/controls/Date.tsx @@ -69,8 +69,8 @@ const FlexSpaced = styled.div(({ theme }) => ({ export type DateProps = ControlProps & DateConfig; export const DateControl: FC = ({ name, value, onChange, onFocus, onBlur, argType }) => { const [valid, setValid] = useState(true); - const dateRef = useRef(); - const timeRef = useRef(); + const dateRef = useRef(null); + const timeRef = useRef(null); const readonly = !!argType?.table?.readonly; useEffect(() => { diff --git a/code/addons/docs/src/blocks/controls/react-editable-json-tree/JsonNodes.tsx b/code/addons/docs/src/blocks/controls/react-editable-json-tree/JsonNodes.tsx index 6de1a7a620cd..3424c8768b49 100644 --- a/code/addons/docs/src/blocks/controls/react-editable-json-tree/JsonNodes.tsx +++ b/code/addons/docs/src/blocks/controls/react-editable-json-tree/JsonNodes.tsx @@ -104,12 +104,12 @@ export class JsonAddValue extends Component { className: 'rejt-minus-menu', style: minus, 'aria-label': `remove the array '${String(name)}'`, - }); + } as any); return ( <> @@ -381,7 +381,7 @@ export class JsonArray extends Component { className: 'rejt-plus-menu', style: plus, 'aria-label': `add a new item to the '${String(name)}' array`, - }); + } as any); const removeItemButton = minusMenuElement && cloneElement(minusMenuElement, { @@ -389,7 +389,7 @@ export class JsonArray extends Component { className: 'rejt-minus-menu', style: minus, 'aria-label': `remove the array '${String(name)}'`, - }); + } as any); const onlyValue = true; const startObject = '['; @@ -674,7 +674,7 @@ export class JsonFunctionValue extends Component { className: 'rejt-minus-menu', style: minus, 'aria-label': `remove the object '${String(name)}'`, - }); + } as any); return ( <> @@ -1270,7 +1270,7 @@ export class JsonObject extends Component { className: 'rejt-plus-menu', style: plus, 'aria-label': `add a new property to the object '${String(name)}'`, - }); + } as any); const removeItemButton = minusMenuElement && cloneElement(minusMenuElement, { @@ -1278,7 +1278,7 @@ export class JsonObject extends Component { className: 'rejt-minus-menu', style: minus, 'aria-label': `remove the object '${String(name)}'`, - }); + } as any); const list = keyList.map((key) => ( { 'aria-label': `remove the property '${String(name)}' with value '${String(originalValue)}'${ String(parentPropertyName) ? ` from '${String(parentPropertyName)}'` : '' }`, - }); + } as any); return (
  • diff --git a/code/addons/jest/package.json b/code/addons/jest/package.json index ccea855aea31..385e8465d53a 100644 --- a/code/addons/jest/package.json +++ b/code/addons/jest/package.json @@ -55,9 +55,9 @@ }, "devDependencies": { "@storybook/icons": "^1.6.0", - "react": "^18.2.0", - "react-dom": "^18.2.0", - "react-resize-detector": "^7.1.2", + "react": "^19.1.1", + "react-dom": "^19.1.1", + "react-resize-detector": "^12.3.0", "typescript": "^5.8.3" }, "peerDependencies": { @@ -66,7 +66,7 @@ "publishConfig": { "access": "public" }, - "gitHead": "a8e7fd8a655c69780bc20b9749d2699e45beae16", + "gitHead": "a8e7fd8a655c69780bc20b9749d2699e45beae18", "storybook": { "displayName": "Jest", "icon": "https://pbs.twimg.com/profile_images/821713465245102080/mMtKIMax_400x400.jpg", diff --git a/code/addons/links/package.json b/code/addons/links/package.json index e14cc1c038ac..909e5d7778c7 100644 --- a/code/addons/links/package.json +++ b/code/addons/links/package.json @@ -71,7 +71,7 @@ "publishConfig": { "access": "public" }, - "gitHead": "a8e7fd8a655c69780bc20b9749d2699e45beae16", + "gitHead": "a8e7fd8a655c69780bc20b9749d2699e45beae18", "storybook": { "displayName": "Links", "icon": "https://user-images.githubusercontent.com/263385/101991673-48355c80-3c7c-11eb-9b6e-b627c96a75f6.png", diff --git a/code/addons/onboarding/package.json b/code/addons/onboarding/package.json index 259e307940fb..3e78a0dcf7ef 100644 --- a/code/addons/onboarding/package.json +++ b/code/addons/onboarding/package.json @@ -53,8 +53,8 @@ "devDependencies": { "@neoconfetti/react": "^1.0.0", "@storybook/icons": "^1.6.0", - "react": "^18.2.0", - "react-dom": "^18.2.0", + "react": "^19.1.1", + "react-dom": "^19.1.1", "react-joyride": "^2.8.2", "typescript": "^5.8.3" }, diff --git a/code/addons/onboarding/src/components/HighlightElement/HighlightElement.tsx b/code/addons/onboarding/src/components/HighlightElement/HighlightElement.tsx index 23fa7489ad68..9d3de3de2510 100644 --- a/code/addons/onboarding/src/components/HighlightElement/HighlightElement.tsx +++ b/code/addons/onboarding/src/components/HighlightElement/HighlightElement.tsx @@ -1,4 +1,4 @@ -import { useEffect } from 'react'; +import { type JSX, useEffect } from 'react'; export function HighlightElement({ targetSelector, diff --git a/code/addons/onboarding/src/manager.tsx b/code/addons/onboarding/src/manager.tsx index 3258b053c51e..2ff9598fca6a 100644 --- a/code/addons/onboarding/src/manager.tsx +++ b/code/addons/onboarding/src/manager.tsx @@ -1,5 +1,5 @@ import React, { Suspense, lazy } from 'react'; -import ReactDOM from 'react-dom'; +import { createRoot } from 'react-dom/client'; import { STORY_SPECIFIED } from 'storybook/internal/core-events'; @@ -45,12 +45,11 @@ addons.register('@storybook/addon-onboarding', async (api) => { document.body.appendChild(domNode); // Render the React app - // eslint-disable-next-line react/no-deprecated - ReactDOM.render( + const root = createRoot(domNode); + root.render( }> - , - domNode + ); }); }); diff --git a/code/addons/pseudo-states/package.json b/code/addons/pseudo-states/package.json index 2c494f95d090..150318739163 100644 --- a/code/addons/pseudo-states/package.json +++ b/code/addons/pseudo-states/package.json @@ -56,8 +56,8 @@ }, "devDependencies": { "@storybook/icons": "^1.6.0", - "react": "^18.2.0", - "react-dom": "^18.2.0", + "react": "^19.1.1", + "react-dom": "^19.1.1", "typescript": "^5.8.3" }, "peerDependencies": { diff --git a/code/addons/themes/package.json b/code/addons/themes/package.json index dee8f0410990..ee691ee36fa6 100644 --- a/code/addons/themes/package.json +++ b/code/addons/themes/package.json @@ -62,8 +62,8 @@ }, "devDependencies": { "@storybook/icons": "^1.6.0", - "react": "^18.2.0", - "react-dom": "^18.2.0", + "react": "^19.1.1", + "react-dom": "^19.1.1", "typescript": "^5.8.3" }, "peerDependencies": { @@ -72,7 +72,7 @@ "publishConfig": { "access": "public" }, - "gitHead": "a8e7fd8a655c69780bc20b9749d2699e45beae16", + "gitHead": "a8e7fd8a655c69780bc20b9749d2699e45beae18", "storybook": { "displayName": "Themes", "unsupportedFrameworks": [ diff --git a/code/addons/vitest/package.json b/code/addons/vitest/package.json index ab559bf5d69b..defc988bb54b 100644 --- a/code/addons/vitest/package.json +++ b/code/addons/vitest/package.json @@ -92,8 +92,8 @@ "micromatch": "^4.0.8", "pathe": "^1.1.2", "picocolors": "^1.1.0", - "react": "^18.2.0", - "react-dom": "^18.2.0", + "react": "^19.1.1", + "react-dom": "^19.1.1", "semver": "^7.6.3", "sirv": "^2.0.4", "slash": "^5.0.0", diff --git a/code/addons/vitest/src/use-test-provider-state.ts b/code/addons/vitest/src/use-test-provider-state.ts index e9ecb3bd77e7..f282b9386457 100644 --- a/code/addons/vitest/src/use-test-provider-state.ts +++ b/code/addons/vitest/src/use-test-provider-state.ts @@ -65,13 +65,15 @@ export const useTestProvider = ( // this follows the same behavior for the green border around the whole testing module in TestingModule.tsx const [isSettingsUpdated, setIsSettingsUpdated] = useState(false); - const settingsUpdatedTimeoutRef = useRef>(); + const settingsUpdatedTimeoutRef = useRef | null>(null); useEffect(() => { const unsubscribe = store.onStateChange((state, previousState) => { if (!isEqual(state.config, previousState.config)) { testProviderStore.settingsChanged(); setIsSettingsUpdated(true); - clearTimeout(settingsUpdatedTimeoutRef.current); + if (settingsUpdatedTimeoutRef.current) { + clearTimeout(settingsUpdatedTimeoutRef.current); + } settingsUpdatedTimeoutRef.current = setTimeout(() => { setIsSettingsUpdated(false); }, 1000); @@ -79,7 +81,9 @@ export const useTestProvider = ( }); return () => { unsubscribe(); - clearTimeout(settingsUpdatedTimeoutRef.current); + if (settingsUpdatedTimeoutRef.current) { + clearTimeout(settingsUpdatedTimeoutRef.current); + } }; }, []); diff --git a/code/builders/builder-vite/package.json b/code/builders/builder-vite/package.json index 7c6428cd4737..350320810ece 100644 --- a/code/builders/builder-vite/package.json +++ b/code/builders/builder-vite/package.json @@ -69,5 +69,5 @@ "publishConfig": { "access": "public" }, - "gitHead": "a8e7fd8a655c69780bc20b9749d2699e45beae16" + "gitHead": "a8e7fd8a655c69780bc20b9749d2699e45beae18" } diff --git a/code/builders/builder-webpack5/package.json b/code/builders/builder-webpack5/package.json index a6d39233af28..5a023d5ef2b8 100644 --- a/code/builders/builder-webpack5/package.json +++ b/code/builders/builder-webpack5/package.json @@ -89,5 +89,5 @@ "publishConfig": { "access": "public" }, - "gitHead": "a8e7fd8a655c69780bc20b9749d2699e45beae16" + "gitHead": "a8e7fd8a655c69780bc20b9749d2699e45beae18" } diff --git a/code/core/package.json b/code/core/package.json index 04366c09b16b..be02d42bcde4 100644 --- a/code/core/package.json +++ b/code/core/package.json @@ -226,10 +226,10 @@ "@ndelangen/get-tarball": "^3.0.7", "@ngard/tiny-isequal": "^1.1.0", "@polka/compression": "^1.0.0-next.28", - "@radix-ui/react-dialog": "^1.1.2", - "@radix-ui/react-scroll-area": "1.2.0-rc.7", - "@radix-ui/react-slot": "^1.0.2", - "@rolldown/pluginutils": "1.0.0-beta.18", + "@radix-ui/react-dialog": "^1.1.15", + "@radix-ui/react-scroll-area": "^1.2.10", + "@radix-ui/react-slot": "^1.2.3", + "@rolldown/pluginutils": "1.0.0-beta.38", "@storybook/docs-mdx": "4.0.0-next.1", "@tanstack/react-virtual": "^3.3.0", "@testing-library/dom": "10.4.0", @@ -246,7 +246,7 @@ "@types/pretty-hrtime": "^1.0.0", "@types/prompts": "^2.0.9", "@types/react-syntax-highlighter": "11.0.5", - "@types/react-transition-group": "^4", + "@types/react-transition-group": "^4.4.12", "@types/semver": "^7.5.8", "@types/ws": "^8", "@vitest/utils": "^3.2.4", @@ -274,6 +274,7 @@ "empathic": "^2.0.0", "es-toolkit": "^1.36.0", "esbuild": "^0.18.0 || ^0.19.0 || ^0.20.0 || ^0.21.0 || ^0.22.0 || ^0.23.0 || ^0.24.0 || ^0.25.0", + "estree-walker": "^3.0.3", "execa": "^8.0.1", "exsolve": "^1.0.7", "fetch-retry": "^6.0.0", @@ -304,14 +305,14 @@ "pretty-hrtime": "^1.0.3", "prompts": "^2.4.0", "qrcode.react": "^4.2.0", - "react": "^18.2.0", - "react-dom": "^18.2.0", - "react-helmet-async": "^1.3.0", - "react-inspector": "^6.0.0", + "react": "^19.1.1", + "react-dom": "^19.1.1", + "react-helmet-async": "^2.0.5", + "react-inspector": "^9.0.0", "react-popper-tooltip": "^4.4.2", "react-router-dom": "6.15.0", - "react-syntax-highlighter": "^15.4.5", - "react-textarea-autosize": "^8.3.0", + "react-syntax-highlighter": "^15.6.6", + "react-textarea-autosize": "^8.5.9", "react-transition-group": "^4.4.5", "require-from-string": "^2.0.2", "resolve.exports": "^2.0.3", @@ -344,5 +345,5 @@ "publishConfig": { "access": "public" }, - "gitHead": "a8e7fd8a655c69780bc20b9749d2699e45beae16" + "gitHead": "a8e7fd8a655c69780bc20b9749d2699e45beae18" } diff --git a/code/core/src/actions/components/ActionLogger/index.tsx b/code/core/src/actions/components/ActionLogger/index.tsx index 1da7339e09c8..e6ce641ff1f0 100644 --- a/code/core/src/actions/components/ActionLogger/index.tsx +++ b/code/core/src/actions/components/ActionLogger/index.tsx @@ -1,4 +1,4 @@ -import type { ElementRef, ReactNode } from 'react'; +import type { ComponentRef, ReactNode } from 'react'; import React, { Fragment, forwardRef, useEffect, useRef } from 'react'; import { ActionBar, ScrollArea } from 'storybook/internal/components'; @@ -42,7 +42,7 @@ interface ActionLoggerProps { } export const ActionLogger = ({ actions, onClear }: ActionLoggerProps) => { - const wrapperRef = useRef>(null); + const wrapperRef = useRef | null>(null); const wrapper = wrapperRef.current; const wasAtBottom = wrapper && wrapper.scrollHeight - wrapper.scrollTop === wrapper.clientHeight; @@ -50,7 +50,7 @@ export const ActionLogger = ({ actions, onClear }: ActionLoggerProps) => { // Scroll to bottom, when the action panel was already scrolled down // Scroll to bottom, when the action panel was already scrolled down - if (wasAtBottom) { + if (wasAtBottom && wrapperRef.current) { wrapperRef.current.scrollTop = wrapperRef.current.scrollHeight; } }, [wasAtBottom, actions.length]); diff --git a/code/core/src/component-testing/components/MethodCall.tsx b/code/core/src/component-testing/components/MethodCall.tsx index cb4fc43a87c2..07cbe71dcbf0 100644 --- a/code/core/src/component-testing/components/MethodCall.tsx +++ b/code/core/src/component-testing/components/MethodCall.tsx @@ -247,6 +247,8 @@ export const ObjectNode = ({ return ( <> ); const setCall = ({ status, ...call }: Call) => calls.current.set(call.id, call); - const endRef = useRef(); + const endRef = useRef(null); useEffect(() => { let observer: IntersectionObserver; if (global.IntersectionObserver) { @@ -416,7 +416,6 @@ export const Panel = memo<{ refId?: string; storyId: string; storyUrl: string }> caughtException={caughtException} unhandledErrors={unhandledErrors} pausedAt={pausedAt} - // @ts-expect-error TODO endRef={endRef} onScrollToEnd={scrollTarget && scrollToTarget} importPath={importPath} diff --git a/code/core/src/components/components/Zoom/ZoomElement.tsx b/code/core/src/components/components/Zoom/ZoomElement.tsx index 550042bbae10..77d38f12ce84 100644 --- a/code/core/src/components/components/Zoom/ZoomElement.tsx +++ b/code/core/src/components/components/Zoom/ZoomElement.tsx @@ -1,4 +1,4 @@ -import type { ReactElement } from 'react'; +import type { ReactElement, RefObject } from 'react'; import React, { useCallback, useEffect, useRef, useState } from 'react'; import { styled } from 'storybook/theming'; @@ -39,7 +39,7 @@ export function ZoomElement({ centered, scale, children }: ZoomProps) { }, [scale]); useResizeObserver({ - ref: componentWrapperRef, + ref: componentWrapperRef as RefObject, onResize, }); diff --git a/code/core/src/components/components/Zoom/ZoomIFrame.tsx b/code/core/src/components/components/Zoom/ZoomIFrame.tsx index d166d3b96c28..662cbd70bc53 100644 --- a/code/core/src/components/components/Zoom/ZoomIFrame.tsx +++ b/code/core/src/components/components/Zoom/ZoomIFrame.tsx @@ -4,7 +4,7 @@ import React, { Component } from 'react'; export type IZoomIFrameProps = { scale: number; children: ReactElement; - iFrameRef: RefObject; + iFrameRef: RefObject; active?: boolean; }; @@ -14,8 +14,7 @@ export class ZoomIFrame extends Component { componentDidMount() { const { iFrameRef } = this.props; - // @ts-expect-error (non strict) - this.iframe = iFrameRef.current; + this.iframe = iFrameRef.current as HTMLIFrameElement; } shouldComponentUpdate(nextProps: IZoomIFrameProps) { diff --git a/code/core/src/components/components/addon-panel/addon-panel.tsx b/code/core/src/components/components/addon-panel/addon-panel.tsx index 8d56028a3293..1dc33249a9c6 100644 --- a/code/core/src/components/components/addon-panel/addon-panel.tsx +++ b/code/core/src/components/components/addon-panel/addon-panel.tsx @@ -1,8 +1,8 @@ import type { ReactElement } from 'react'; import React, { useEffect, useRef } from 'react'; -const usePrevious = (value: any) => { - const ref = useRef(); +const usePrevious = (value: ReactElement) => { + const ref = useRef(undefined); useEffect(() => { // happens after return @@ -12,7 +12,7 @@ const usePrevious = (value: any) => { return ref.current; }; -const useUpdate = (update: boolean, value: any) => { +const useUpdate = (update: boolean, value: ReactElement) => { const previousValue = usePrevious(value); return update ? value : previousValue; diff --git a/code/core/src/components/components/tabs/tabs.helpers.tsx b/code/core/src/components/components/tabs/tabs.helpers.tsx index 7e51d48625a4..04cce8e5adef 100644 --- a/code/core/src/components/components/tabs/tabs.helpers.tsx +++ b/code/core/src/components/components/tabs/tabs.helpers.tsx @@ -1,4 +1,4 @@ -import type { FC, PropsWithChildren, ReactChild, ReactElement, ReactNode } from 'react'; +import type { FC, PropsWithChildren, ReactElement, ReactNode } from 'react'; import React, { Children } from 'react'; import type { Addon_RenderOptions } from 'storybook/internal/types'; @@ -21,8 +21,8 @@ export const childrenToList = (children: TabsProps['children']) => ({ props: { title, id, color, children: childrenOfChild }, }: ReactElement<{ - children: FC | ReactChild | null; - title: ReactChild | null | FC; + children: FC | ReactElement | null; + title: ReactElement | FC | string | number | null | boolean | undefined; id: string; color?: string; }>) => { diff --git a/code/core/src/components/components/tabs/tabs.hooks.tsx b/code/core/src/components/components/tabs/tabs.hooks.tsx index 60c4f49c0d9c..18afcfc41220 100644 --- a/code/core/src/components/components/tabs/tabs.hooks.tsx +++ b/code/core/src/components/components/tabs/tabs.hooks.tsx @@ -39,8 +39,8 @@ const AddonButton = styled(TabButton)<{ preActive: boolean }>(({ active, theme, }); export function useList(list: ChildrenListComplete) { - const tabBarRef = useRef(); - const addonsRef = useRef(); + const tabBarRef = useRef(null); + const addonsRef = useRef(null); const tabRefs = useRef(new Map()); const { width: tabBarWidth = 1 } = useResizeObserver({ // @ts-expect-error (non strict) @@ -91,7 +91,6 @@ export function useList(list: ChildrenListComplete) { > = memo( // @ts-expect-error (non strict) - {/* @ts-expect-error (non strict) */} {visibleList.map(({ title, id, active, color }, index) => { const indexId = `index-${index}`; diff --git a/code/core/src/components/components/tooltip/WithTooltip.tsx b/code/core/src/components/components/tooltip/WithTooltip.tsx index 20252273e6b8..1f066d713ef3 100644 --- a/code/core/src/components/components/tooltip/WithTooltip.tsx +++ b/code/core/src/components/components/tooltip/WithTooltip.tsx @@ -1,4 +1,4 @@ -import type { ComponentProps, ReactNode } from 'react'; +import type { ComponentProps, ComponentType, ReactElement, ReactNode } from 'react'; import React, { useCallback, useEffect, useState } from 'react'; import ReactDOM from 'react-dom'; @@ -35,7 +35,7 @@ export interface WithTooltipPureProps svg?: boolean; withArrows?: boolean; hasChrome?: boolean; - tooltip: ReactNode | ((p: WithHideFn) => ReactNode); + tooltip: ReactElement | ComponentType; children: ReactNode; onDoubleClick?: () => void; /** diff --git a/code/core/src/highlight/StoryContent.tsx b/code/core/src/highlight/StoryContent.tsx index 132e4f1c6337..58a981e64c28 100644 --- a/code/core/src/highlight/StoryContent.tsx +++ b/code/core/src/highlight/StoryContent.tsx @@ -20,9 +20,7 @@ export const StoryContent = ({
    {withPopover && ( <> - {/* @ts-expect-error popover is not yet supported by React */} - - {/* @ts-expect-error popover is not yet supported by React */} +
    Greetings, one and all!
    diff --git a/code/core/src/manager/components/sidebar/FileSearchList.tsx b/code/core/src/manager/components/sidebar/FileSearchList.tsx index 15593113ad2f..787558a2cd46 100644 --- a/code/core/src/manager/components/sidebar/FileSearchList.tsx +++ b/code/core/src/manager/components/sidebar/FileSearchList.tsx @@ -1,4 +1,4 @@ -import React, { memo, useCallback, useMemo, useState } from 'react'; +import React, { memo, useCallback, useMemo, useRef, useState } from 'react'; import { TooltipNote, WithTooltip } from 'storybook/internal/components'; import type { @@ -84,7 +84,7 @@ export const FileSearchList = memo(function FileSearchList({ errorItemId, }: FileSearchListProps) { const [selectedItem, setSelectedItem] = useState(null); - const parentRef = React.useRef(); + const parentRef = useRef(null); const sortedSearchResults = useMemo(() => { // search results with no exports should be at the end of the list @@ -119,7 +119,6 @@ export const FileSearchList = memo(function FileSearchList({ const rowVirtualizer = useVirtualizer({ count, - // @ts-expect-error (non strict) getScrollElement: () => parentRef.current, paddingStart: 16, @@ -291,7 +290,6 @@ export const FileSearchList = memo(function FileSearchList({ if (sortedSearchResults?.length > 0) { return ( - {/* @ts-expect-error (non strict) */} { - const ref = useRef(null); + const ref = useRef(null); const renderLink = ({ id, diff --git a/code/core/src/manager/components/sidebar/TestingModule.tsx b/code/core/src/manager/components/sidebar/TestingModule.tsx index d63a68feaacd..5bf57ebb9643 100644 --- a/code/core/src/manager/components/sidebar/TestingModule.tsx +++ b/code/core/src/manager/components/sidebar/TestingModule.tsx @@ -201,37 +201,53 @@ export const TestingModule = ({ const [isCollapsed, setCollapsed] = useState(true); const [isChangingCollapse, setChangingCollapse] = useState(false); const [isUpdated, setIsUpdated] = useState(false); - const settingsUpdatedTimeoutRef = useRef>(); + const settingsUpdatedTimeoutRef = useRef>(null); useEffect(() => { const unsubscribe = internal_fullTestProviderStore.onSettingsChanged(() => { setIsUpdated(true); - clearTimeout(settingsUpdatedTimeoutRef.current); + if (settingsUpdatedTimeoutRef.current) { + clearTimeout(settingsUpdatedTimeoutRef.current); + } settingsUpdatedTimeoutRef.current = setTimeout(() => { setIsUpdated(false); }, 1000); }); return () => { unsubscribe(); - clearTimeout(settingsUpdatedTimeoutRef.current); + if (settingsUpdatedTimeoutRef.current) { + clearTimeout(settingsUpdatedTimeoutRef.current); + } }; }, []); useEffect(() => { + let rf: number | null = null; if (contentRef.current) { - setMaxHeight(contentRef.current?.getBoundingClientRect().height || DEFAULT_HEIGHT); + rf = requestAnimationFrame(() => { + if (contentRef.current && !isCollapsed) { + const height = contentRef.current.getBoundingClientRect().height || DEFAULT_HEIGHT; + + setMaxHeight(height); + } + }); const resizeObserver = new ResizeObserver(() => { - requestAnimationFrame(() => { + rf = requestAnimationFrame(() => { if (contentRef.current && !isCollapsed) { - const height = contentRef.current?.getBoundingClientRect().height || DEFAULT_HEIGHT; + const height = contentRef.current.getBoundingClientRect().height || DEFAULT_HEIGHT; setMaxHeight(height); } }); }); resizeObserver.observe(contentRef.current); - return () => resizeObserver.disconnect(); + return () => { + resizeObserver.disconnect(); + if (rf) { + cancelAnimationFrame(rf); + } + }; } }, [isCollapsed]); @@ -427,7 +443,7 @@ export const TestingModule = ({ {hasTestProviders && ( {}; export const useExpanded = ({ @@ -77,19 +76,11 @@ export const useExpanded = ({ // Track the set of currently expanded nodes within this tree. // Root nodes are expanded by default. - const [expanded, setExpanded] = useReducer< - Reducer, - { - refId: string; - data: StoriesHash; - highlightedRef: MutableRefObject; - rootIds: string[]; - initialExpanded: ExpandedState; - } - >( - (state, { ids, value }) => - ids.reduce((acc, id) => Object.assign(acc, { [id]: value }), { ...state }), - // @ts-expect-error (non strict) + const [expanded, setExpanded] = useReducer( + (state: ExpandedState, { ids, value }: ExpandAction) => + ids.reduce((acc: ExpandedState, id: string) => Object.assign(acc, { [id]: value }), { + ...state, + }), { refId, data, highlightedRef, rootIds, initialExpanded }, initializeExpanded ); @@ -101,8 +92,10 @@ export const useExpanded = ({ const highlightElement = useCallback( (element: Element) => { - // @ts-expect-error (non strict) - setHighlightedItemId(element.getAttribute('data-item-id')); + const itemId = element.getAttribute('data-item-id'); + if (itemId) { + setHighlightedItemId(itemId); + } scrollIntoView(element); }, [setHighlightedItemId] @@ -110,7 +103,6 @@ export const useExpanded = ({ const updateExpanded = useCallback( ({ ids, value }: ExpandAction) => { - // @ts-expect-error (non strict) setExpanded({ ids, value }); if (ids.length === 1) { const element = containerRef.current?.querySelector( @@ -127,18 +119,17 @@ export const useExpanded = ({ // Expand the whole ancestry of the currently selected story whenever it changes. useEffect(() => { - // @ts-expect-error (non strict) - setExpanded({ ids: getAncestorIds(data, selectedStoryId), value: true }); + if (selectedStoryId) { + setExpanded({ ids: getAncestorIds(data, selectedStoryId), value: true }); + } }, [data, selectedStoryId]); const collapseAll = useCallback(() => { const ids = Object.keys(data).filter((id) => !rootIds.includes(id)); - // @ts-expect-error (non strict) setExpanded({ ids, value: false }); }, [data, rootIds]); const expandAll = useCallback(() => { - // @ts-expect-error (non strict) setExpanded({ ids: Object.keys(data), value: true }); }, [data]); @@ -190,8 +181,7 @@ export const useExpanded = ({ const target = event.target as Element; - // @ts-expect-error (non strict) - if (!isAncestor(menuElement, target) && !isAncestor(target, menuElement)) { + if (menuElement && !isAncestor(menuElement, target) && !isAncestor(target, menuElement)) { return; } if (target.hasAttribute('data-action')) { @@ -215,7 +205,6 @@ export const useExpanded = ({ if (isArrowLeft) { if (isExpanded === 'true') { // The highlighted node is expanded, so we collapse it. - // @ts-expect-error (non strict) setExpanded({ ids: [highlightedItemId], value: false }); return; } @@ -230,7 +219,6 @@ export const useExpanded = ({ // The parent can't be highlighted, which means it must be a root. // The highlighted node is already collapsed, so we collapse its descendants. - // @ts-expect-error (non strict) setExpanded({ ids: getDescendantIds(data, highlightedItemId, true), value: false }); return; } diff --git a/code/core/src/manager/globals/exports.ts b/code/core/src/manager/globals/exports.ts index b717d6296d56..bcb08cce553c 100644 --- a/code/core/src/manager/globals/exports.ts +++ b/code/core/src/manager/globals/exports.ts @@ -11,19 +11,23 @@ export default { 'PureComponent', 'StrictMode', 'Suspense', - '__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED', + '__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE', + '__COMPILER_RUNTIME', 'act', + 'cache', + 'captureOwnerStack', 'cloneElement', 'createContext', 'createElement', - 'createFactory', 'createRef', 'forwardRef', 'isValidElement', 'lazy', 'memo', 'startTransition', - 'unstable_act', + 'unstable_useCacheRefresh', + 'use', + 'useActionState', 'useCallback', 'useContext', 'useDebugValue', @@ -34,6 +38,7 @@ export default { 'useInsertionEffect', 'useLayoutEffect', 'useMemo', + 'useOptimistic', 'useReducer', 'useRef', 'useState', @@ -42,20 +47,22 @@ export default { 'version', ], 'react-dom': [ - '__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED', + '__DOM_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE', 'createPortal', - 'createRoot', - 'findDOMNode', 'flushSync', - 'hydrate', - 'hydrateRoot', - 'render', - 'unmountComponentAtNode', + 'preconnect', + 'prefetchDNS', + 'preinit', + 'preinitModule', + 'preload', + 'preloadModule', + 'requestFormReset', 'unstable_batchedUpdates', - 'unstable_renderSubtreeIntoContainer', + 'useFormState', + 'useFormStatus', 'version', ], - 'react-dom/client': ['createRoot', 'hydrateRoot'], + 'react-dom/client': ['createRoot', 'hydrateRoot', 'version'], '@storybook/icons': [ 'AccessibilityAltIcon', 'AccessibilityIcon', diff --git a/code/core/src/types/modules/addons.ts b/code/core/src/types/modules/addons.ts index 01f56adc965f..84d580aaa494 100644 --- a/code/core/src/types/modules/addons.ts +++ b/code/core/src/types/modules/addons.ts @@ -374,7 +374,7 @@ export interface Addon_BaseType { * This is called as a function, so if you want to use hooks, your function needs to return a * JSX.Element within which components are rendered */ - render: (props: Partial) => ReturnType>>; + render: (props: Partial) => ReactNode; // TODO: for Storybook 9 I'd like to change this to be: // render: FC>; // This would bring it in line with how every other addon is set up. diff --git a/code/frameworks/angular/package.json b/code/frameworks/angular/package.json index c7b7aa386638..a9e532ebc03e 100644 --- a/code/frameworks/angular/package.json +++ b/code/frameworks/angular/package.json @@ -122,5 +122,5 @@ "access": "public" }, "builders": "builders.json", - "gitHead": "a8e7fd8a655c69780bc20b9749d2699e45beae16" + "gitHead": "a8e7fd8a655c69780bc20b9749d2699e45beae18" } diff --git a/code/frameworks/ember/package.json b/code/frameworks/ember/package.json index 7587b4f04ca0..070901195821 100644 --- a/code/frameworks/ember/package.json +++ b/code/frameworks/ember/package.json @@ -71,5 +71,5 @@ "publishConfig": { "access": "public" }, - "gitHead": "a8e7fd8a655c69780bc20b9749d2699e45beae16" + "gitHead": "a8e7fd8a655c69780bc20b9749d2699e45beae18" } diff --git a/code/frameworks/html-vite/package.json b/code/frameworks/html-vite/package.json index 8daac1fc85af..831e39936535 100644 --- a/code/frameworks/html-vite/package.json +++ b/code/frameworks/html-vite/package.json @@ -63,5 +63,5 @@ "publishConfig": { "access": "public" }, - "gitHead": "a8e7fd8a655c69780bc20b9749d2699e45beae16" + "gitHead": "a8e7fd8a655c69780bc20b9749d2699e45beae18" } diff --git a/code/frameworks/nextjs-vite/package.json b/code/frameworks/nextjs-vite/package.json index ab32c2131d86..b0979676edcc 100644 --- a/code/frameworks/nextjs-vite/package.json +++ b/code/frameworks/nextjs-vite/package.json @@ -107,5 +107,5 @@ "publishConfig": { "access": "public" }, - "gitHead": "a8e7fd8a655c69780bc20b9749d2699e45beae16" + "gitHead": "a8e7fd8a655c69780bc20b9749d2699e45beae18" } diff --git a/code/frameworks/nextjs-vite/src/head-manager/head-manager-provider.tsx b/code/frameworks/nextjs-vite/src/head-manager/head-manager-provider.tsx index 69b58866c510..0a27e88a52f3 100644 --- a/code/frameworks/nextjs-vite/src/head-manager/head-manager-provider.tsx +++ b/code/frameworks/nextjs-vite/src/head-manager/head-manager-provider.tsx @@ -1,4 +1,4 @@ -import type { PropsWithChildren } from 'react'; +import type { JSX, PropsWithChildren } from 'react'; import React, { useMemo } from 'react'; import initHeadManager from 'next/dist/client/head-manager'; diff --git a/code/frameworks/nextjs/package.json b/code/frameworks/nextjs/package.json index 1ef54af00623..704142d6c02b 100644 --- a/code/frameworks/nextjs/package.json +++ b/code/frameworks/nextjs/package.json @@ -144,5 +144,5 @@ "publishConfig": { "access": "public" }, - "gitHead": "a8e7fd8a655c69780bc20b9749d2699e45beae16" + "gitHead": "a8e7fd8a655c69780bc20b9749d2699e45beae18" } diff --git a/code/frameworks/nextjs/src/head-manager/head-manager-provider.tsx b/code/frameworks/nextjs/src/head-manager/head-manager-provider.tsx index 69b58866c510..0a27e88a52f3 100644 --- a/code/frameworks/nextjs/src/head-manager/head-manager-provider.tsx +++ b/code/frameworks/nextjs/src/head-manager/head-manager-provider.tsx @@ -1,4 +1,4 @@ -import type { PropsWithChildren } from 'react'; +import type { JSX, PropsWithChildren } from 'react'; import React, { useMemo } from 'react'; import initHeadManager from 'next/dist/client/head-manager'; diff --git a/code/frameworks/preact-vite/package.json b/code/frameworks/preact-vite/package.json index 01f65c562489..cb52cf7fcc10 100644 --- a/code/frameworks/preact-vite/package.json +++ b/code/frameworks/preact-vite/package.json @@ -66,5 +66,5 @@ "publishConfig": { "access": "public" }, - "gitHead": "a8e7fd8a655c69780bc20b9749d2699e45beae16" + "gitHead": "a8e7fd8a655c69780bc20b9749d2699e45beae18" } diff --git a/code/frameworks/react-native-web-vite/package.json b/code/frameworks/react-native-web-vite/package.json index dcb92363e9d0..3d1a57dae7d6 100644 --- a/code/frameworks/react-native-web-vite/package.json +++ b/code/frameworks/react-native-web-vite/package.json @@ -74,5 +74,5 @@ "publishConfig": { "access": "public" }, - "gitHead": "a8e7fd8a655c69780bc20b9749d2699e45beae16" + "gitHead": "a8e7fd8a655c69780bc20b9749d2699e45beae18" } diff --git a/code/frameworks/react-vite/package.json b/code/frameworks/react-vite/package.json index 8a405c712bbd..20c08ae48f44 100644 --- a/code/frameworks/react-vite/package.json +++ b/code/frameworks/react-vite/package.json @@ -77,5 +77,5 @@ "publishConfig": { "access": "public" }, - "gitHead": "a8e7fd8a655c69780bc20b9749d2699e45beae16" + "gitHead": "a8e7fd8a655c69780bc20b9749d2699e45beae18" } diff --git a/code/frameworks/react-webpack5/package.json b/code/frameworks/react-webpack5/package.json index c7782e4343e6..41e7b7ad4ae9 100644 --- a/code/frameworks/react-webpack5/package.json +++ b/code/frameworks/react-webpack5/package.json @@ -71,5 +71,5 @@ "publishConfig": { "access": "public" }, - "gitHead": "a8e7fd8a655c69780bc20b9749d2699e45beae16" + "gitHead": "a8e7fd8a655c69780bc20b9749d2699e45beae18" } diff --git a/code/frameworks/server-webpack5/package.json b/code/frameworks/server-webpack5/package.json index a55a234c1996..2c4f5c453965 100644 --- a/code/frameworks/server-webpack5/package.json +++ b/code/frameworks/server-webpack5/package.json @@ -62,5 +62,5 @@ "publishConfig": { "access": "public" }, - "gitHead": "a8e7fd8a655c69780bc20b9749d2699e45beae16" + "gitHead": "a8e7fd8a655c69780bc20b9749d2699e45beae18" } diff --git a/code/frameworks/svelte-vite/package.json b/code/frameworks/svelte-vite/package.json index 2f85939fd98e..6db7935de868 100644 --- a/code/frameworks/svelte-vite/package.json +++ b/code/frameworks/svelte-vite/package.json @@ -76,5 +76,5 @@ "publishConfig": { "access": "public" }, - "gitHead": "a8e7fd8a655c69780bc20b9749d2699e45beae16" + "gitHead": "a8e7fd8a655c69780bc20b9749d2699e45beae18" } diff --git a/code/frameworks/sveltekit/package.json b/code/frameworks/sveltekit/package.json index 24d22ad77346..38277a647fc2 100644 --- a/code/frameworks/sveltekit/package.json +++ b/code/frameworks/sveltekit/package.json @@ -76,5 +76,5 @@ "publishConfig": { "access": "public" }, - "gitHead": "a8e7fd8a655c69780bc20b9749d2699e45beae16" + "gitHead": "a8e7fd8a655c69780bc20b9749d2699e45beae18" } diff --git a/code/frameworks/sveltekit/tsconfig.json b/code/frameworks/sveltekit/tsconfig.json index 39029c2ce294..f5ab5afaf6a4 100644 --- a/code/frameworks/sveltekit/tsconfig.json +++ b/code/frameworks/sveltekit/tsconfig.json @@ -3,7 +3,7 @@ "baseUrl": ".", "paths": { "storybook/internal/*": ["../../lib/cli/core/*"] - }, + } }, "extends": "../../tsconfig.json", "include": ["src/**/*"] diff --git a/code/frameworks/vue3-vite/package.json b/code/frameworks/vue3-vite/package.json index fc87bcbef5a6..4441566b64b1 100644 --- a/code/frameworks/vue3-vite/package.json +++ b/code/frameworks/vue3-vite/package.json @@ -70,5 +70,5 @@ "publishConfig": { "access": "public" }, - "gitHead": "a8e7fd8a655c69780bc20b9749d2699e45beae16" + "gitHead": "a8e7fd8a655c69780bc20b9749d2699e45beae18" } diff --git a/code/frameworks/web-components-vite/package.json b/code/frameworks/web-components-vite/package.json index 6d64453fc8b9..d04869746992 100644 --- a/code/frameworks/web-components-vite/package.json +++ b/code/frameworks/web-components-vite/package.json @@ -65,5 +65,5 @@ "publishConfig": { "access": "public" }, - "gitHead": "a8e7fd8a655c69780bc20b9749d2699e45beae16" + "gitHead": "a8e7fd8a655c69780bc20b9749d2699e45beae18" } diff --git a/code/lib/cli-sb/package.json b/code/lib/cli-sb/package.json index 5151bf00a3d0..1a3d02be58a7 100644 --- a/code/lib/cli-sb/package.json +++ b/code/lib/cli-sb/package.json @@ -31,5 +31,5 @@ "publishConfig": { "access": "public" }, - "gitHead": "a8e7fd8a655c69780bc20b9749d2699e45beae16" + "gitHead": "a8e7fd8a655c69780bc20b9749d2699e45beae18" } diff --git a/code/lib/cli-storybook/package.json b/code/lib/cli-storybook/package.json index 431728549bee..0eca3677ae71 100644 --- a/code/lib/cli-storybook/package.json +++ b/code/lib/cli-storybook/package.json @@ -72,5 +72,5 @@ "publishConfig": { "access": "public" }, - "gitHead": "a8e7fd8a655c69780bc20b9749d2699e45beae16" + "gitHead": "a8e7fd8a655c69780bc20b9749d2699e45beae18" } diff --git a/code/lib/codemod/package.json b/code/lib/codemod/package.json index 95049a9cea15..a5768697676b 100644 --- a/code/lib/codemod/package.json +++ b/code/lib/codemod/package.json @@ -62,5 +62,5 @@ "publishConfig": { "access": "public" }, - "gitHead": "a8e7fd8a655c69780bc20b9749d2699e45beae16" + "gitHead": "a8e7fd8a655c69780bc20b9749d2699e45beae18" } diff --git a/code/lib/core-webpack/package.json b/code/lib/core-webpack/package.json index 69c9fb2ca62b..3899df71bf68 100644 --- a/code/lib/core-webpack/package.json +++ b/code/lib/core-webpack/package.json @@ -53,5 +53,5 @@ "publishConfig": { "access": "public" }, - "gitHead": "a8e7fd8a655c69780bc20b9749d2699e45beae16" + "gitHead": "a8e7fd8a655c69780bc20b9749d2699e45beae18" } diff --git a/code/lib/create-storybook/package.json b/code/lib/create-storybook/package.json index 17cda16cbd6f..bd8026227fd5 100644 --- a/code/lib/create-storybook/package.json +++ b/code/lib/create-storybook/package.json @@ -56,7 +56,7 @@ "picocolors": "^1.1.0", "process-ancestry": "^0.0.2", "prompts": "^2.4.0", - "react": "^18.2.0", + "react": "^19.1.1", "tiny-invariant": "^1.3.1", "ts-dedent": "^2.0.0", "typescript": "^5.8.3" @@ -64,5 +64,5 @@ "publishConfig": { "access": "public" }, - "gitHead": "a8e7fd8a655c69780bc20b9749d2699e45beae16" + "gitHead": "a8e7fd8a655c69780bc20b9749d2699e45beae18" } diff --git a/code/lib/csf-plugin/package.json b/code/lib/csf-plugin/package.json index bcfb1cfc79a5..185d787882e8 100644 --- a/code/lib/csf-plugin/package.json +++ b/code/lib/csf-plugin/package.json @@ -70,5 +70,5 @@ "publishConfig": { "access": "public" }, - "gitHead": "a8e7fd8a655c69780bc20b9749d2699e45beae16" + "gitHead": "a8e7fd8a655c69780bc20b9749d2699e45beae18" } diff --git a/code/lib/eslint-plugin/package.json b/code/lib/eslint-plugin/package.json index 1e6cb86883f4..4ec61f31d51f 100644 --- a/code/lib/eslint-plugin/package.json +++ b/code/lib/eslint-plugin/package.json @@ -68,5 +68,5 @@ "publishConfig": { "access": "public" }, - "gitHead": "a8e7fd8a655c69780bc20b9749d2699e45beae16" + "gitHead": "a8e7fd8a655c69780bc20b9749d2699e45beae18" } diff --git a/code/lib/eslint-plugin/scripts/generate-rule.ts b/code/lib/eslint-plugin/scripts/generate-rule.ts index a7ef1dc1596d..a49f7a0c40f6 100644 --- a/code/lib/eslint-plugin/scripts/generate-rule.ts +++ b/code/lib/eslint-plugin/scripts/generate-rule.ts @@ -2,6 +2,7 @@ import cp from 'node:child_process'; import fs from 'node:fs/promises'; import path from 'node:path'; +import { format, resolveConfig } from 'prettier'; import type { PromptObject } from 'prompts'; import prompts from 'prompts'; import { dedent } from 'ts-dedent'; @@ -154,82 +155,94 @@ const generateRule = async () => { logger.log(`creating tests/rules/${ruleId}.test.ts`); await fs.writeFile( testFile, - dedent(`/** - * @fileoverview ${ruleDescription} - * @author ${authorName} - */ + await format( + dedent( + `/** + * @fileoverview ${ruleDescription} + * @author ${authorName} + */ - //------------------------------------------------------------------------------ - // Requirements - //------------------------------------------------------------------------------ - - import rule from '../../src/rules/${ruleId}' - import ruleTester from '../utils/rule-tester' - - //------------------------------------------------------------------------------ - // Tests - //------------------------------------------------------------------------------ - - ruleTester.run('${ruleId}', rule, { - /** - * 👉 Please read this and delete this entire comment block. - * This is an example test for a rule that reports an error in case a named export is called 'wrong' - * Use https://eslint.org/docs/developer-guide/working-with-rules for Eslint API reference - */ - valid: ['export const correct = {}'], - invalid: [ - { - code: 'export const wrong = {}', - errors: [ - { - messageId: 'anyMessageIdHere', // comes from the rule file - }, - ], - }, - ], - }) + //------------------------------------------------------------------------------ + // Requirements + //------------------------------------------------------------------------------ -`) + import rule from '../../src/rules/${ruleId}' + import ruleTester from '../utils/rule-tester' + + //------------------------------------------------------------------------------ + // Tests + //------------------------------------------------------------------------------ + + ruleTester.run('${ruleId}', rule, { + /** + * 👉 Please read this and delete this entire comment block. + * This is an example test for a rule that reports an error in case a named export is called 'wrong' + * Use https://eslint.org/docs/developer-guide/working-with-rules for Eslint API reference + */ + valid: ['export const correct = {}'], + invalid: [ + { + code: 'export const wrong = {}', + errors: [ + { + messageId: 'anyMessageIdHere', // comes from the rule file + }, + ], + }, + ], + }) + ` + ), + { + parser: 'typescript', + ...(await resolveConfig(__dirname)), + } + ) ); logger.log(`creating docs/rules/${ruleId}.md`); await fs.writeFile( docFile, - dedent(` - # ${ruleId} - - - + await format( + dedent(` + # ${ruleId} - ## Rule Details + + - ${ruleDescription}. + ## Rule Details - Examples of **incorrect** code for this rule: + ${ruleDescription}. - \`\`\`js - // fill me in - \`\`\` + Examples of **incorrect** code for this rule: - Examples of **correct** code for this rule: + \`\`\`js + // fill me in + \`\`\` - \`\`\`js - // fill me in - \`\`\` + Examples of **correct** code for this rule: - ### Options + \`\`\`js + // fill me in + \`\`\` - If there are any options, describe them here. Otherwise, delete this section. + ### Options - ## When Not To Use It + If there are any options, describe them here. Otherwise, delete this section. - Give a short description of when it would be appropriate to turn off this rule. If not applicable, delete this section. + ## When Not To Use It - ## Further Reading + Give a short description of when it would be appropriate to turn off this rule. If not applicable, delete this section. - If there are other links that describe the issue this rule addresses, please include them here in a bulleted list. Otherwise, delete this section. + ## Further Reading -`) + If there are other links that describe the issue this rule addresses, please include them here in a bulleted list. Otherwise, delete this section. + `), + { + parser: 'markdown', + ...(await resolveConfig(__dirname)), + } + ) ); const { shouldOpenInVSCode } = await prompts({ diff --git a/code/lib/react-dom-shim/package.json b/code/lib/react-dom-shim/package.json index 8270958f3ee2..f67944e177f0 100644 --- a/code/lib/react-dom-shim/package.json +++ b/code/lib/react-dom-shim/package.json @@ -52,5 +52,5 @@ "publishConfig": { "access": "public" }, - "gitHead": "a8e7fd8a655c69780bc20b9749d2699e45beae16" + "gitHead": "a8e7fd8a655c69780bc20b9749d2699e45beae18" } diff --git a/code/lib/react-dom-shim/src/react-16.tsx b/code/lib/react-dom-shim/src/react-16.tsx index 8c7b2c8f5a67..94abaa594062 100644 --- a/code/lib/react-dom-shim/src/react-16.tsx +++ b/code/lib/react-dom-shim/src/react-16.tsx @@ -4,10 +4,12 @@ import * as ReactDOM from 'react-dom'; export const renderElement = async (node: ReactElement, el: Element) => { return new Promise((resolve) => { + // @ts-expect-error (Converted from ts-ignore) ReactDOM.render(node, el, () => resolve(null)); }); }; export const unmountElement = (el: Element) => { + // @ts-expect-error (Converted from ts-ignore) ReactDOM.unmountComponentAtNode(el); }; diff --git a/code/lib/react-dom-shim/src/react-18.tsx b/code/lib/react-dom-shim/src/react-18.tsx index f3398fc65ff0..f589865d98c7 100644 --- a/code/lib/react-dom-shim/src/react-18.tsx +++ b/code/lib/react-dom-shim/src/react-18.tsx @@ -20,6 +20,7 @@ const WithCallback: React.FC<{ callback: () => void; children: ReactElement }> = children, }) => { // See https://github.com/reactwg/react-18/discussions/5#discussioncomment-2276079 + // @ts-expect-error - React18 allowed this const once = React.useRef<() => void>(); React.useLayoutEffect(() => { if (once.current === callback) { @@ -32,7 +33,7 @@ const WithCallback: React.FC<{ callback: () => void; children: ReactElement }> = return children; }; -// pony-fill +// pony-fill for Promise.withResolvers (ES2024 feature) if (typeof Promise.withResolvers === 'undefined') { Promise.withResolvers = () => { let resolve: PromiseWithResolvers['resolve'] = null!; diff --git a/code/package.json b/code/package.json index 07746bdecc20..c8b3cda6adf2 100644 --- a/code/package.json +++ b/code/package.json @@ -94,12 +94,12 @@ "@types/babel__traverse@npm:*": "patch:@types/babel__traverse@npm%3A7.20.6#~/.yarn/patches/@types-babel__traverse-npm-7.20.6-fac4243243.patch", "@types/babel__traverse@npm:^7.18.0": "patch:@types/babel__traverse@npm%3A7.20.6#~/.yarn/patches/@types-babel__traverse-npm-7.20.6-fac4243243.patch", "@types/node": "^22.0.0", - "@types/react": "^18.0.0", + "@types/react": "^19.0.0", "@vitest/expect@npm:3.2.4": "patch:@vitest/expect@npm%3A3.2.4#~/.yarn/patches/@vitest-expect-npm-3.2.4-97c526d5cc.patch", "esbuild": "^0.25.3", "playwright": "1.52.0", "playwright-core": "1.52.0", - "react": "^18.2.0", + "react": "^19.1.1", "serialize-javascript": "^3.1.0", "type-fest": "~2.19", "typescript": "^5.8.3" @@ -152,8 +152,8 @@ "@types/lodash-es": "^4.17.12", "@types/mock-require": "^2.0.3", "@types/node": "^22.0.0", - "@types/react": "^18.0.37", - "@types/react-dom": "^18.0.11", + "@types/react": "^19.1.12", + "@types/react-dom": "^19.1.9", "@typescript-eslint/eslint-plugin": "^8.8.1", "@typescript-eslint/parser": "^8.8.1", "@vitejs/plugin-react": "^4.3.2", @@ -201,8 +201,8 @@ "prettier-plugin-jsdoc": "^1.3.0", "prettier-plugin-merge": "^0.7.0", "process": "^0.11.10", - "react": "^18.2.0", - "react-dom": "^18.2.0", + "react": "^19.1.1", + "react-dom": "^19.1.1", "rimraf": "^6.0.1", "slash": "^5.0.0", "sort-package-json": "^2.14.0", diff --git a/code/presets/create-react-app/package.json b/code/presets/create-react-app/package.json index 90e576fc9dec..54261cdb4c23 100644 --- a/code/presets/create-react-app/package.json +++ b/code/presets/create-react-app/package.json @@ -53,5 +53,5 @@ "publishConfig": { "access": "public" }, - "gitHead": "a8e7fd8a655c69780bc20b9749d2699e45beae16" + "gitHead": "a8e7fd8a655c69780bc20b9749d2699e45beae18" } diff --git a/code/presets/react-webpack/package.json b/code/presets/react-webpack/package.json index d512e644e451..6889501f0424 100644 --- a/code/presets/react-webpack/package.json +++ b/code/presets/react-webpack/package.json @@ -70,5 +70,5 @@ "publishConfig": { "access": "public" }, - "gitHead": "a8e7fd8a655c69780bc20b9749d2699e45beae16" + "gitHead": "a8e7fd8a655c69780bc20b9749d2699e45beae18" } diff --git a/code/presets/server-webpack/package.json b/code/presets/server-webpack/package.json index 9b31395dfeb0..619031ac42e9 100644 --- a/code/presets/server-webpack/package.json +++ b/code/presets/server-webpack/package.json @@ -56,5 +56,5 @@ "publishConfig": { "access": "public" }, - "gitHead": "a8e7fd8a655c69780bc20b9749d2699e45beae16" + "gitHead": "a8e7fd8a655c69780bc20b9749d2699e45beae18" } diff --git a/code/renderers/html/package.json b/code/renderers/html/package.json index d518908d646c..22b86872620f 100644 --- a/code/renderers/html/package.json +++ b/code/renderers/html/package.json @@ -59,5 +59,5 @@ "publishConfig": { "access": "public" }, - "gitHead": "a8e7fd8a655c69780bc20b9749d2699e45beae16" + "gitHead": "a8e7fd8a655c69780bc20b9749d2699e45beae18" } diff --git a/code/renderers/preact/package.json b/code/renderers/preact/package.json index d7ef19c17833..8cacce1e8932 100644 --- a/code/renderers/preact/package.json +++ b/code/renderers/preact/package.json @@ -61,5 +61,5 @@ "publishConfig": { "access": "public" }, - "gitHead": "a8e7fd8a655c69780bc20b9749d2699e45beae16" + "gitHead": "a8e7fd8a655c69780bc20b9749d2699e45beae18" } diff --git a/code/renderers/preact/src/render.tsx b/code/renderers/preact/src/render.tsx index 56c599006e86..9b3d00918204 100644 --- a/code/renderers/preact/src/render.tsx +++ b/code/renderers/preact/src/render.tsx @@ -16,8 +16,6 @@ export const render: ArgsStoryFn = (args, context) => { ); } - // @ts-expect-error I think the type of Component should be Preact.ComponentType, but even that - // doesn't make TS happy, I suspect because TS wants "react" components. return ; }; diff --git a/code/renderers/react/package.json b/code/renderers/react/package.json index 805fcab3c507..12ffa7b5c581 100644 --- a/code/renderers/react/package.json +++ b/code/renderers/react/package.json @@ -91,5 +91,5 @@ "publishConfig": { "access": "public" }, - "gitHead": "a8e7fd8a655c69780bc20b9749d2699e45beae16" + "gitHead": "a8e7fd8a655c69780bc20b9749d2699e45beae18" } diff --git a/code/renderers/react/src/csf-factories.test.tsx b/code/renderers/react/src/csf-factories.test.tsx index 03b0de64da0a..661c485bd7f9 100644 --- a/code/renderers/react/src/csf-factories.test.tsx +++ b/code/renderers/react/src/csf-factories.test.tsx @@ -3,7 +3,7 @@ import { describe, it } from 'vitest'; import { expect, test } from 'vitest'; -import type { ComponentType, KeyboardEventHandler, ReactElement, ReactNode } from 'react'; +import type { ComponentType, JSX, KeyboardEventHandler, ReactElement, ReactNode } from 'react'; import React from 'react'; import type { Canvas } from 'storybook/internal/csf'; diff --git a/code/renderers/react/src/docs/jsxDecorator.test.tsx b/code/renderers/react/src/docs/jsxDecorator.test.tsx index be425ae2233b..d181cf22b3de 100644 --- a/code/renderers/react/src/docs/jsxDecorator.test.tsx +++ b/code/renderers/react/src/docs/jsxDecorator.test.tsx @@ -5,6 +5,7 @@ import { beforeEach, describe, expect, it, vi } from 'vitest'; import type { FC, PropsWithChildren } from 'react'; import React, { Profiler, StrictMode, createElement } from 'react'; +// @ts-expect-error (Converted from ts-ignore) import PropTypes from 'prop-types'; import { addons, emitTransformCode, useState } from 'storybook/preview-api'; diff --git a/code/renderers/react/src/docs/jsxDecorator.tsx b/code/renderers/react/src/docs/jsxDecorator.tsx index 1d1048c2e624..8c2c280042d2 100644 --- a/code/renderers/react/src/docs/jsxDecorator.tsx +++ b/code/renderers/react/src/docs/jsxDecorator.tsx @@ -54,10 +54,13 @@ export const getReactSymbolName = (elementType: any): string => { // Note: It may be better to use this function only in development environment. function simplifyNodeForStringify(node: ReactNode): ReactNode { if (isValidElement(node)) { - const props = Object.keys(node.props).reduce<{ [key: string]: any }>((acc, cur) => { - acc[cur] = simplifyNodeForStringify(node.props[cur]); - return acc; - }, {}); + const props = Object.keys(node.props as Record).reduce<{ [key: string]: any }>( + (acc, cur) => { + acc[cur] = simplifyNodeForStringify((node.props as Record)[cur]); + return acc; + }, + {} + ); return { ...node, props, @@ -104,16 +107,18 @@ export const renderJsx = (code: React.ReactElement, options?: JSXOptions) => { return null; } - if (typeof renderedJSX.props.children === 'undefined') { + const props = renderedJSX.props as Record; + + if (typeof props.children === 'undefined') { logger.warn('Not enough children to skip elements.'); if (typeof renderedJSX.type === 'function' && renderedJSX.type.name === '') { - renderedJSX = ; + renderedJSX = ; } - } else if (typeof renderedJSX.props.children === 'function') { - renderedJSX = renderedJSX.props.children(); + } else if (typeof props.children === 'function') { + renderedJSX = props.children(); } else { - renderedJSX = renderedJSX.props.children; + renderedJSX = props.children; } } diff --git a/code/renderers/react/src/docs/propTypes/handleProp.test.tsx b/code/renderers/react/src/docs/propTypes/handleProp.test.tsx index aa50241af4d7..20e1c661c8e0 100644 --- a/code/renderers/react/src/docs/propTypes/handleProp.test.tsx +++ b/code/renderers/react/src/docs/propTypes/handleProp.test.tsx @@ -9,6 +9,7 @@ import { extractComponentProps, } from 'storybook/internal/docs-tools'; +// @ts-expect-error (no longer valid/typed with React 19) import PropTypes from 'prop-types'; import { enhancePropTypesProp, enhancePropTypesProps } from './handleProp'; diff --git a/code/renderers/react/src/public-types.test.tsx b/code/renderers/react/src/public-types.test.tsx index 45a36ab1d015..8e417e520cd1 100644 --- a/code/renderers/react/src/public-types.test.tsx +++ b/code/renderers/react/src/public-types.test.tsx @@ -2,7 +2,7 @@ // this file tests Typescript types that's why there are no assertions import { describe, it } from 'vitest'; -import type { KeyboardEventHandler, ReactElement, ReactNode } from 'react'; +import type { JSX, KeyboardEventHandler, ReactElement, ReactNode } from 'react'; import React from 'react'; import { satisfies } from 'storybook/internal/common'; diff --git a/code/renderers/react/template/stories/docgen-components/10278-ts-multiple-components/input.tsx b/code/renderers/react/template/stories/docgen-components/10278-ts-multiple-components/input.tsx index 4490901b9790..9bf15289f6c0 100644 --- a/code/renderers/react/template/stories/docgen-components/10278-ts-multiple-components/input.tsx +++ b/code/renderers/react/template/stories/docgen-components/10278-ts-multiple-components/input.tsx @@ -1,5 +1,5 @@ /* eslint-disable react/destructuring-assignment */ -import React from 'react'; +import React, { type JSX } from 'react'; interface IAProps { aProperty: any; diff --git a/code/renderers/react/template/stories/docgen-components/8740-ts-multi-props/docgen.snapshot b/code/renderers/react/template/stories/docgen-components/8740-ts-multi-props/docgen.snapshot index 12be491a61b6..2d77d6da8002 100644 --- a/code/renderers/react/template/stories/docgen-components/8740-ts-multi-props/docgen.snapshot +++ b/code/renderers/react/template/stories/docgen-components/8740-ts-multi-props/docgen.snapshot @@ -11,6 +11,8 @@ export const Paragraph = ({ }) => /*#__PURE__*/React.createElement("div", { className: size }, children); + +// @ts-expect-error (Converted from ts-ignore) Paragraph.defaultProps = { size: 'md' }; diff --git a/code/renderers/react/template/stories/docgen-components/8740-ts-multi-props/input.tsx b/code/renderers/react/template/stories/docgen-components/8740-ts-multi-props/input.tsx index 1fb6607d0b71..c7985b6f8249 100644 --- a/code/renderers/react/template/stories/docgen-components/8740-ts-multi-props/input.tsx +++ b/code/renderers/react/template/stories/docgen-components/8740-ts-multi-props/input.tsx @@ -18,6 +18,7 @@ export const Paragraph: React.FC = ({ size, children }) => (
    {children}
    ); +// @ts-expect-error (Converted from ts-ignore) Paragraph.defaultProps = { size: 'md' }; export const component = Header; diff --git a/code/renderers/react/template/stories/docgen-components/9575-ts-camel-case/docgen.snapshot b/code/renderers/react/template/stories/docgen-components/9575-ts-camel-case/docgen.snapshot index 71d4150ec9d1..2f62caa3c685 100644 --- a/code/renderers/react/template/stories/docgen-components/9575-ts-camel-case/docgen.snapshot +++ b/code/renderers/react/template/stories/docgen-components/9575-ts-camel-case/docgen.snapshot @@ -1,4 +1,6 @@ import React from 'react'; + +// @ts-expect-error (Converted from ts-ignore) import PropTypes from 'prop-types'; const iconButton = function IconButton(props) { return /*#__PURE__*/React.createElement("div", { @@ -9,6 +11,8 @@ iconButton.propTypes = { // deepscan-disable-next-line color: PropTypes.string }; + +// @ts-expect-error (Converted from ts-ignore) iconButton.defaultProps = { color: 'primary' }; diff --git a/code/renderers/react/template/stories/docgen-components/9575-ts-camel-case/input.tsx b/code/renderers/react/template/stories/docgen-components/9575-ts-camel-case/input.tsx index feee06599e1f..f2f751467cfe 100644 --- a/code/renderers/react/template/stories/docgen-components/9575-ts-camel-case/input.tsx +++ b/code/renderers/react/template/stories/docgen-components/9575-ts-camel-case/input.tsx @@ -1,6 +1,7 @@ import type { FC } from 'react'; import React from 'react'; +// @ts-expect-error (Converted from ts-ignore) import PropTypes from 'prop-types'; export interface IProps { @@ -17,6 +18,7 @@ iconButton.propTypes = { color: PropTypes.string, }; +// @ts-expect-error (Converted from ts-ignore) iconButton.defaultProps = { color: 'primary', }; diff --git a/code/renderers/react/template/stories/docgen-components/ts-function-component/input.tsx b/code/renderers/react/template/stories/docgen-components/ts-function-component/input.tsx index ba15a430f025..0945b5e28d0f 100644 --- a/code/renderers/react/template/stories/docgen-components/ts-function-component/input.tsx +++ b/code/renderers/react/template/stories/docgen-components/ts-function-component/input.tsx @@ -37,6 +37,7 @@ export const PropsWriter: React.FC = (props: PropsWriterProps)
    {JSON.stringify(props)}
    ); +// @ts-expect-error (Converted from ts-ignore) PropsWriter.defaultProps = { numberOptional: 1, stringOptional: 'stringOptional', diff --git a/code/renderers/react/template/stories/docgen-components/ts-types/docgen.snapshot b/code/renderers/react/template/stories/docgen-components/ts-types/docgen.snapshot index 8b77d5696cdb..657dff529ac6 100644 --- a/code/renderers/react/template/stories/docgen-components/ts-types/docgen.snapshot +++ b/code/renderers/react/template/stories/docgen-components/ts-types/docgen.snapshot @@ -21,6 +21,7 @@ var StringEnum = /*#__PURE__*/function (StringEnum) { return StringEnum; }(StringEnum || {}); export const TypeScriptProps = () => /*#__PURE__*/React.createElement("div", null, "TypeScript!"); +// @ts-expect-error (Converted from ts-ignore) TypeScriptProps.defaultProps = { any: 'Any value', string: 'A string value', diff --git a/code/renderers/react/template/stories/docgen-components/ts-types/input.tsx b/code/renderers/react/template/stories/docgen-components/ts-types/input.tsx index 4cb8703a9daa..cf67d05e6cf2 100644 --- a/code/renderers/react/template/stories/docgen-components/ts-types/input.tsx +++ b/code/renderers/react/template/stories/docgen-components/ts-types/input.tsx @@ -93,6 +93,7 @@ interface TypeScriptPropsProps { } export const TypeScriptProps: FC = () =>
    TypeScript!
    ; +// @ts-expect-error (Converted from ts-ignore) TypeScriptProps.defaultProps = { any: 'Any value', string: 'A string value', diff --git a/code/renderers/server/package.json b/code/renderers/server/package.json index eeee4a4a7290..580dc0f09fef 100644 --- a/code/renderers/server/package.json +++ b/code/renderers/server/package.json @@ -58,5 +58,5 @@ "publishConfig": { "access": "public" }, - "gitHead": "a8e7fd8a655c69780bc20b9749d2699e45beae16" + "gitHead": "a8e7fd8a655c69780bc20b9749d2699e45beae18" } diff --git a/code/renderers/svelte/package.json b/code/renderers/svelte/package.json index 77cd8bc43fc0..c44fe2387700 100644 --- a/code/renderers/svelte/package.json +++ b/code/renderers/svelte/package.json @@ -75,5 +75,5 @@ "publishConfig": { "access": "public" }, - "gitHead": "a8e7fd8a655c69780bc20b9749d2699e45beae16" + "gitHead": "a8e7fd8a655c69780bc20b9749d2699e45beae18" } diff --git a/code/renderers/vue3/package.json b/code/renderers/vue3/package.json index 98ff41bf0646..fc5dd384cd13 100644 --- a/code/renderers/vue3/package.json +++ b/code/renderers/vue3/package.json @@ -69,5 +69,5 @@ "publishConfig": { "access": "public" }, - "gitHead": "a8e7fd8a655c69780bc20b9749d2699e45beae16" + "gitHead": "a8e7fd8a655c69780bc20b9749d2699e45beae18" } diff --git a/code/renderers/vue3/template/stories_vue3-vite-default-ts/component-meta/class-slots/component.vue b/code/renderers/vue3/template/stories_vue3-vite-default-ts/component-meta/class-slots/component.vue index a3491292f5d4..81fca068b089 100644 --- a/code/renderers/vue3/template/stories_vue3-vite-default-ts/component-meta/class-slots/component.vue +++ b/code/renderers/vue3/template/stories_vue3-vite-default-ts/component-meta/class-slots/component.vue @@ -1,7 +1,12 @@