diff --git a/packages/next/src/next-devtools/dev-overlay/components/devtools-indicator/devtools-indicator.tsx b/packages/next/src/next-devtools/dev-overlay/components/devtools-indicator/devtools-indicator.tsx index 776ab0d8b423..0cf967371d82 100644 --- a/packages/next/src/next-devtools/dev-overlay/components/devtools-indicator/devtools-indicator.tsx +++ b/packages/next/src/next-devtools/dev-overlay/components/devtools-indicator/devtools-indicator.tsx @@ -10,11 +10,10 @@ import { } from '../errors/dev-tools-indicator/utils' import { ACTION_DEVTOOLS_PANEL_TOGGLE, - ACTION_ERROR_OVERLAY_TOGGLE, - ACTION_ERROR_OVERLAY_CLOSE, STORAGE_KEY_POSITION, - ACTION_DEVTOOLS_PANEL_CLOSE, ACTION_DEVTOOLS_POSITION, + ACTION_DEVTOOLS_PANEL_OPEN, + ACTION_ERROR_OVERLAY_OPEN, } from '../../shared' import { Draggable } from '../errors/dev-tools-indicator/draggable' @@ -35,13 +34,13 @@ export function DevToolsIndicator({ const [vertical, horizontal] = state.devToolsPosition.split('-', 2) - const toggleErrorOverlay = () => { - dispatch({ type: ACTION_DEVTOOLS_PANEL_CLOSE }) - dispatch({ type: ACTION_ERROR_OVERLAY_TOGGLE }) + const enableErrorOverlayMode = () => { + dispatch({ type: ACTION_ERROR_OVERLAY_OPEN }) + // Open the DevTools panel to view as error overlay mode. + dispatch({ type: ACTION_DEVTOOLS_PANEL_OPEN }) } const toggleDevToolsPanel = () => { - dispatch({ type: ACTION_ERROR_OVERLAY_CLOSE }) dispatch({ type: ACTION_DEVTOOLS_PANEL_TOGGLE }) } @@ -56,7 +55,10 @@ export function DevToolsIndicator({ zIndex: 2147483647, [vertical]: `${INDICATOR_PADDING}px`, [horizontal]: `${INDICATOR_PADDING}px`, - visibility: state.isDevToolsPanelOpen ? 'hidden' : 'visible', + visibility: + state.isDevToolsPanelOpen || state.isErrorOverlayOpen + ? 'hidden' + : 'visible', } as CSSProperties } > @@ -82,7 +84,7 @@ export function DevToolsIndicator({ disabled={state.disableDevIndicator} issueCount={errorCount} onTriggerClick={toggleDevToolsPanel} - toggleErrorOverlay={toggleErrorOverlay} + toggleErrorOverlay={enableErrorOverlayMode} isDevBuilding={state.buildingIndicator} isDevRendering={state.renderingIndicator} isBuildError={isBuildError} diff --git a/packages/next/src/next-devtools/dev-overlay/components/devtools-panel/devtools-panel.tsx b/packages/next/src/next-devtools/dev-overlay/components/devtools-panel/devtools-panel.tsx index 70a06ed2a585..009db927eb97 100644 --- a/packages/next/src/next-devtools/dev-overlay/components/devtools-panel/devtools-panel.tsx +++ b/packages/next/src/next-devtools/dev-overlay/components/devtools-panel/devtools-panel.tsx @@ -14,6 +14,7 @@ import { ACTION_DEVTOOLS_SCALE, STORAGE_KEY_SCALE, STORAGE_KEY_POSITION, + ACTION_ERROR_OVERLAY_CLOSE, } from '../../shared' import { css } from '../../utils/css' import { OverlayBackdrop } from '../overlay' @@ -40,10 +41,20 @@ export function DevToolsPanel({ }) { const [activeTab, setActiveTab] = useState('issues') const [isFullscreen, setIsFullscreen] = useState(false) + const [prevIsErrorOverlayOpen, setPrevIsErrorOverlayOpen] = useState(false) + + if (state.isErrorOverlayOpen !== prevIsErrorOverlayOpen) { + if (state.isErrorOverlayOpen) { + setIsFullscreen(true) + } + setPrevIsErrorOverlayOpen(state.isErrorOverlayOpen) + } + const [vertical, horizontal] = state.devToolsPosition.split('-', 2) const onCloseDevToolsPanel = () => { dispatch({ type: ACTION_DEVTOOLS_PANEL_CLOSE }) + dispatch({ type: ACTION_ERROR_OVERLAY_CLOSE }) } const handlePositionChange = (e: React.ChangeEvent) => { @@ -64,6 +75,7 @@ export function DevToolsPanel({ const handleFullscreenToggle = () => { setIsFullscreen((prev) => !prev) + dispatch({ type: ACTION_ERROR_OVERLAY_CLOSE }) } return ( diff --git a/packages/next/src/next-devtools/dev-overlay/dev-overlay.tsx b/packages/next/src/next-devtools/dev-overlay/dev-overlay.tsx index 8c3d52226cb1..8c05f69fad11 100644 --- a/packages/next/src/next-devtools/dev-overlay/dev-overlay.tsx +++ b/packages/next/src/next-devtools/dev-overlay/dev-overlay.tsx @@ -1,4 +1,11 @@ -import type { OverlayDispatch, OverlayState } from './shared' +import { + ACTION_DEVTOOLS_PANEL_OPEN, + ACTION_ERROR_OVERLAY_OPEN, + type OverlayDispatch, + type OverlayState, +} from './shared' + +import { useState } from 'react' import { ShadowPortal } from './components/shadow-portal' import { Base } from './styles/base' @@ -24,6 +31,23 @@ export function DevOverlay({ getSquashedHydrationErrorDetails: (error: Error) => HydrationErrorState | null }) { const [scale, setScale] = useDevToolsScale() + const [isPrevBuildError, setIsPrevBuildError] = useState(false) + + const isBuildError = state.buildError !== null + + if ( + process.env.__NEXT_DEVTOOL_NEW_PANEL_UI && + isBuildError !== isPrevBuildError + ) { + // If the build error is set, enable the devtools panel as the error overlay mode, + // and the rest actions (close, minimize, fullscreen) can be handled by the user. + if (isBuildError) { + dispatch({ type: ACTION_DEVTOOLS_PANEL_OPEN }) + dispatch({ type: ACTION_ERROR_OVERLAY_OPEN }) + } + setIsPrevBuildError(isBuildError) + } + return ( @@ -36,7 +60,6 @@ export function DevOverlay({ {({ runtimeErrors, totalErrorCount }) => { - const isBuildError = state.buildError !== null return ( <> {state.showIndicator && @@ -49,7 +72,8 @@ export function DevOverlay({ isBuildError={isBuildError} /> - {state.isDevToolsPanelOpen && ( + {(state.isDevToolsPanelOpen || + state.isErrorOverlayOpen) && ( ) : ( - - ))} + <> + - + + + ))} ) }} diff --git a/packages/next/src/next-devtools/dev-overlay/shared.ts b/packages/next/src/next-devtools/dev-overlay/shared.ts index 92bea8610102..1440ab082ff8 100644 --- a/packages/next/src/next-devtools/dev-overlay/shared.ts +++ b/packages/next/src/next-devtools/dev-overlay/shared.ts @@ -38,6 +38,10 @@ export interface OverlayState { disableDevIndicator: boolean debugInfo: DebugInfo routerType: 'pages' | 'app' + /** This flag is used to handle the Error Overlay state in the "old" overlay. + * In the DevTools panel, this value will used for the "Error Overlay Mode" + * which is viewing the "Issues Tab" as a fullscreen. + */ isErrorOverlayOpen: boolean isDevToolsPanelOpen: boolean devToolsPosition: Corners diff --git a/packages/next/src/next-devtools/dev-overlay/storybook/use-overlay-reducer.ts b/packages/next/src/next-devtools/dev-overlay/storybook/use-overlay-reducer.ts index 5f859623895e..be8fa3eb44b4 100644 --- a/packages/next/src/next-devtools/dev-overlay/storybook/use-overlay-reducer.ts +++ b/packages/next/src/next-devtools/dev-overlay/storybook/use-overlay-reducer.ts @@ -10,6 +10,7 @@ import { ACTION_ERROR_OVERLAY_TOGGLE, ACTION_DEVTOOLS_SCALE, INITIAL_OVERLAY_STATE, + ACTION_DEVTOOLS_PANEL_OPEN, } from '../shared' export const storybookDefaultOverlayState: OverlayState = { @@ -42,6 +43,9 @@ export function useStorybookOverlayReducer(initialState?: OverlayState) { case ACTION_DEVTOOLS_PANEL_CLOSE: { return { ...state, isDevToolsPanelOpen: false } } + case ACTION_DEVTOOLS_PANEL_OPEN: { + return { ...state, isDevToolsPanelOpen: true } + } case ACTION_DEVTOOLS_POSITION: { return { ...state, devToolsPosition: action.devToolsPosition } }