Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,20 +1,30 @@
import type { DevToolsPanelTabType } from '../devtools-panel'
import type { Corners } from '../../../shared'
import type { DebugInfo } from '../../../../shared/types'
import type { ReadyRuntimeError } from '../../../utils/get-error-by-type'
import type { HydrationErrorState } from '../../../../shared/hydration-error'

import { SettingsTab } from './settings-tab'
import { IssuesTab } from './issues-tab/issues-tab'

export function DevToolsPanelTab({
activeTab,
devToolsPosition,
scale,
handlePositionChange,
handleScaleChange,
debugInfo,
runtimeErrors,
getSquashedHydrationErrorDetails,
}: {
activeTab: DevToolsPanelTabType
devToolsPosition: Corners
scale: number
handlePositionChange: (e: React.ChangeEvent<HTMLSelectElement>) => void
handleScaleChange: (e: React.ChangeEvent<HTMLSelectElement>) => void
debugInfo: DebugInfo
runtimeErrors: ReadyRuntimeError[]
getSquashedHydrationErrorDetails: (error: Error) => HydrationErrorState | null
}) {
switch (activeTab) {
case 'settings':
Expand All @@ -29,7 +39,13 @@ export function DevToolsPanelTab({
case 'route':
return <div>Route</div>
case 'issues':
return <div>Issues</div>
return (
<IssuesTab
debugInfo={debugInfo}
runtimeErrors={runtimeErrors}
getSquashedHydrationErrorDetails={getSquashedHydrationErrorDetails}
/>
)
default:
return null
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
import type { DebugInfo } from '../../../../../shared/types'
import type { ReadyRuntimeError } from '../../../../utils/get-error-by-type'
import type { HydrationErrorState } from '../../../../../shared/hydration-error'

import {
GenericErrorDescription,
HydrationErrorDescription,
} from '../../../../container/errors'
import { EnvironmentNameLabel } from '../../../errors/environment-name-label/environment-name-label'
import { ErrorMessage } from '../../../errors/error-message/error-message'
import { ErrorOverlayToolbar } from '../../../errors/error-overlay-toolbar/error-overlay-toolbar'
import { ErrorTypeLabel } from '../../../errors/error-type-label/error-type-label'
import { css } from '../../../../utils/css'
import { useActiveRuntimeError } from '../../../../hooks/use-active-runtime-error'

export function IssuesTab({
debugInfo,
runtimeErrors,
getSquashedHydrationErrorDetails,
}: {
debugInfo: DebugInfo
runtimeErrors: ReadyRuntimeError[]
getSquashedHydrationErrorDetails: (error: Error) => HydrationErrorState | null
}) {
const { isLoading, errorCode, errorType, hydrationWarning, activeError } =
useActiveRuntimeError({ runtimeErrors, getSquashedHydrationErrorDetails })

if (isLoading) {
// TODO: better loading state
return null
}

if (!activeError) {
return null
}

const errorMessage = hydrationWarning ? (
<HydrationErrorDescription message={hydrationWarning} />
) : (
<GenericErrorDescription error={activeError.error} />
)

return (
<div data-nextjs-devtools-panel-tab-issues>
{/* TODO: Sidebar */}
<aside>Sidebar</aside>
<div data-nextjs-devtools-panel-tab-issues-content>
<div className="nextjs-container-errors-header">
<div
className="nextjs__container_errors__error_title"
// allow assertion in tests before error rating is implemented
data-nextjs-error-code={errorCode}
>
<span data-nextjs-error-label-group>
<ErrorTypeLabel errorType={errorType} />
{activeError.error.environmentName && (
<EnvironmentNameLabel
environmentName={activeError.error.environmentName}
/>
)}
</span>
<ErrorOverlayToolbar
error={activeError.error}
debugInfo={debugInfo}
/>
</div>
<ErrorMessage errorMessage={errorMessage} />
</div>

{/* TODO: Content */}
<div>Content</div>
</div>
</div>
)
}

export const DEVTOOLS_PANEL_TAB_ISSUES_STYLES = css`
[data-nextjs-devtools-panel-tab-issues] {
display: flex;
}
`
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import type { OverlayState } from '../../shared'
import { DevToolsPanel } from './devtools-panel'
import { INITIAL_OVERLAY_STATE } from '../../shared'
import { withShadowPortal } from '../../storybook/with-shadow-portal'
import { runtimeErrors } from '../../storybook/errors'

const meta: Meta<typeof DevToolsPanel> = {
component: DevToolsPanel,
Expand Down Expand Up @@ -34,6 +35,8 @@ export const Default: Story = {
state,
dispatch: () => {},
issueCount: 0,
runtimeErrors: [],
getSquashedHydrationErrorDetails: () => null,
},
}

Expand All @@ -42,6 +45,8 @@ export const WithIssues: Story = {
state,
dispatch: () => {},
issueCount: 3,
runtimeErrors,
getSquashedHydrationErrorDetails: () => null,
},
}

Expand All @@ -58,6 +63,8 @@ export const Turbopack: Story = {
state,
dispatch: () => {},
issueCount: 0,
runtimeErrors: [],
getSquashedHydrationErrorDetails: () => null,
},
}

Expand All @@ -74,5 +81,7 @@ export const Rspack: Story = {
state,
dispatch: () => {},
issueCount: 0,
runtimeErrors: [],
getSquashedHydrationErrorDetails: () => null,
},
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import type { OverlayDispatch, OverlayState, Corners } from '../../shared'
import type { ReadyRuntimeError } from '../../utils/get-error-by-type'
import type { HydrationErrorState } from '../../../shared/hydration-error'

import { useState } from 'react'

Expand Down Expand Up @@ -26,10 +28,14 @@ export function DevToolsPanel({
state,
dispatch,
issueCount,
runtimeErrors,
getSquashedHydrationErrorDetails,
}: {
state: OverlayState
dispatch: OverlayDispatch
issueCount: number
runtimeErrors: ReadyRuntimeError[]
getSquashedHydrationErrorDetails: (error: Error) => HydrationErrorState | null
}) {
const [activeTab, setActiveTab] = useState<'issues' | 'route' | 'settings'>(
'settings'
Expand Down Expand Up @@ -144,6 +150,11 @@ export function DevToolsPanel({
scale={state.scale}
handlePositionChange={handlePositionChange}
handleScaleChange={handleScaleChange}
debugInfo={state.debugInfo}
runtimeErrors={runtimeErrors}
getSquashedHydrationErrorDetails={
getSquashedHydrationErrorDetails
}
/>
</DialogBody>
</DialogContent>
Expand All @@ -156,6 +167,11 @@ export function DevToolsPanel({
}

export const DEVTOOLS_PANEL_STYLES = css`
/* TODO: Better override dialog header style. This conflicts with issues tab content. */
[data-nextjs-devtools-panel-dialog-header] {
margin-bottom: 0 !important;
}

[data-nextjs-devtools-panel-overlay] {
padding: initial;
margin: auto;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,19 +1,9 @@
import * as React from 'react'
export type DialogHeaderProps = React.HTMLAttributes<HTMLDivElement>

export type DialogHeaderProps = {
children?: React.ReactNode
className?: string
}

const DialogHeader: React.FC<DialogHeaderProps> = function DialogHeader({
children,
className,
}) {
export function DialogHeader(props: DialogHeaderProps) {
return (
<div data-nextjs-dialog-header className={className}>
{children}
<div data-nextjs-dialog-header {...props}>
{props.children}
</div>
)
}

export { DialogHeader }
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,11 @@ function isNextjsLink(text: string): boolean {
return text.startsWith('https://nextjs.org')
}

function HydrationErrorDescription({ message }: { message: string }) {
export function HydrationErrorDescription({ message }: { message: string }) {
return <HotlinkedText text={message} matcher={isNextjsLink} />
}

function GenericErrorDescription({ error }: { error: Error }) {
export function GenericErrorDescription({ error }: { error: Error }) {
const environmentName =
'environmentName' in error ? error.environmentName : ''
const envPrefix = environmentName ? `[ ${environmentName} ] ` : ''
Expand Down
4 changes: 4 additions & 0 deletions packages/next/src/next-devtools/dev-overlay/dev-overlay.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,10 @@ export function DevOverlay({
state={state}
dispatch={dispatch}
issueCount={totalErrorCount}
runtimeErrors={runtimeErrors}
getSquashedHydrationErrorDetails={
getSquashedHydrationErrorDetails
}
/>
)}
</>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import { DEVTOOLS_PANEL_FOOTER_STYLES } from '../components/devtools-panel/devto
import { DEVTOOLS_PANEL_VERSION_INFO_STYLES } from '../components/devtools-panel/devtools-panel-version-info'
import { DEVTOOLS_PANEL_TAB_SETTINGS_STYLES } from '../components/devtools-panel/devtools-panel-tab/settings-tab'
import { CALL_STACK_STYLES } from '../components/call-stack/call-stack'
import { DEVTOOLS_PANEL_TAB_ISSUES_STYLES } from '../components/devtools-panel/devtools-panel-tab/issues-tab/issues-tab'

export function ComponentStyles() {
return (
Expand Down Expand Up @@ -64,6 +65,7 @@ export function ComponentStyles() {
${DEVTOOLS_PANEL_FOOTER_STYLES}
${DEVTOOLS_PANEL_VERSION_INFO_STYLES}
${DEVTOOLS_PANEL_TAB_SETTINGS_STYLES}
${DEVTOOLS_PANEL_TAB_ISSUES_STYLES}
`}
</style>
)
Expand Down