Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Create ErrorOverlay component #74073

Merged
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
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -278,7 +278,8 @@
"scheduler": "0.25.0-rc-372ec00c-20241209"
},
"patchedDependencies": {
"[email protected]": "patches/[email protected]"
"[email protected]": "patches/[email protected]",
"@storybook/[email protected]": "patches/@[email protected]"
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

}
}
}
20 changes: 17 additions & 3 deletions packages/next/.storybook/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,9 @@ function getAbsolutePath(value: string): any {
}
const config: StorybookConfig = {
stories: [
'../stories/**/*.mdx',
'../stories/**/*.stories.@(js|jsx|mjs|ts|tsx)',
// Could to '../src/**/*.stories.@(ts|tsx)', but not sure how much it'll affect perf.
// Scoped to experimental dev overlay for now.
'../src/client/components/react-dev-overlay/_experimental/**/*.stories.@(ts|tsx)',
],
addons: [
getAbsolutePath('@storybook/addon-webpack5-compiler-swc'),
Expand All @@ -23,7 +24,20 @@ const config: StorybookConfig = {
],
framework: {
name: getAbsolutePath('@storybook/react-webpack5'),
options: {},
options: {
builder: {
useSWC: true,
},
},
},
swc: () => ({
jsc: {
transform: {
react: {
runtime: 'automatic',
},
},
},
}),
}
export default config
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import type { Meta, StoryObj } from '@storybook/react'
import { ErrorOverlayLayout } from './ErrorOverlayLayout'
import { withShadowPortal } from '../../storybook/with-shadow-portal'

const meta: Meta<typeof ErrorOverlayLayout> = {
title: 'ErrorOverlayLayout',
component: ErrorOverlayLayout,
parameters: {
layout: 'fullscreen',
},
decorators: [withShadowPortal],
}

export default meta
type Story = StoryObj<typeof ErrorOverlayLayout>

export const Default: Story = {
args: {
errorType: 'Build Error',
errorMessage: 'Failed to compile',
versionInfo: {
installed: '15.0.0',
staleness: 'fresh',
},
children: "Module not found: Cannot find module './missing-module'",
},
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import type { VersionInfo } from '../../../../../../../server/dev/parse-version-info'
import { Dialog, DialogHeader, DialogBody, DialogContent } from '../Dialog'
import { Overlay } from '../Overlay'
import { VersionStalenessInfo } from '../VersionStalenessInfo'

type ErrorOverlayLayoutProps = {
errorType:
| 'Build Error'
| 'Runtime Error'
| 'Console Error'
| 'Unhandled Runtime Error'
| 'Missing Required HTML Tag'
errorMessage: string | React.ReactNode
onClose: () => void
isBuildError?: boolean
versionInfo?: VersionInfo
children?: React.ReactNode
}

export function ErrorOverlayLayout({
errorType,
errorMessage,
onClose,
children,
versionInfo,
isBuildError,
}: ErrorOverlayLayoutProps) {
return (
<Overlay fixed={isBuildError}>
<Dialog
type="error"
aria-labelledby="nextjs__container_errors_label"
aria-describedby="nextjs__container_errors_desc"
onClose={onClose}
>
<DialogContent>
<DialogHeader className="nextjs-container-errors-header">
<h1
id="nextjs__container_errors_label"
className="nextjs__container_errors_label"
>
{errorType}
</h1>
<VersionStalenessInfo versionInfo={versionInfo} />
<p
id="nextjs__container_errors_desc"
className="nextjs__container_errors_desc"
>
{errorMessage}
</p>
</DialogHeader>
<DialogBody className="nextjs-container-errors-body">
{children}
</DialogBody>
</DialogContent>
</Dialog>
</Overlay>
)
}
Original file line number Diff line number Diff line change
@@ -1,15 +1,8 @@
import * as React from 'react'
import type { VersionInfo } from '../../../../../../server/dev/parse-version-info'
import {
Dialog,
DialogBody,
DialogContent,
DialogHeader,
} from '../components/Dialog'
import { Overlay } from '../components/Overlay'
import { Terminal } from '../components/Terminal'
import { VersionStalenessInfo } from '../components/VersionStalenessInfo'
import { noop as css } from '../helpers/noop-template'
import { ErrorOverlayLayout } from '../components/ErrorOverlayLayout/ErrorOverlayLayout'

export type BuildErrorProps = { message: string; versionInfo?: VersionInfo }

Expand All @@ -19,43 +12,22 @@ export const BuildError: React.FC<BuildErrorProps> = function BuildError({
}) {
const noop = React.useCallback(() => {}, [])
return (
<Overlay fixed>
<Dialog
type="error"
aria-labelledby="nextjs__container_errors_label"
aria-describedby="nextjs__container_errors_desc"
onClose={noop}
>
<DialogContent>
<DialogHeader className="nextjs-container-errors-header">
<h1
id="nextjs__container_errors_label"
className="nextjs__container_errors_label"
>
{'Build Error'}
</h1>
<VersionStalenessInfo versionInfo={versionInfo} />
<p
id="nextjs__container_errors_desc"
className="nextjs__container_errors_desc"
>
Failed to compile
</p>
</DialogHeader>
<DialogBody className="nextjs-container-errors-body">
<Terminal content={message} />
<footer>
<p id="nextjs__container_build_error_desc">
<small>
This error occurred during the build process and can only be
dismissed by fixing the error.
</small>
</p>
</footer>
</DialogBody>
</DialogContent>
</Dialog>
</Overlay>
<ErrorOverlayLayout
errorType="Build Error"
errorMessage="Failed to compile"
onClose={noop}
versionInfo={versionInfo}
>
<Terminal content={message} />
<footer>
<p id="nextjs__container_build_error_desc">
<small>
This error occurred during the build process and can only be
dismissed by fixing the error.
</small>
</p>
</footer>
</ErrorOverlayLayout>
)
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,50 +1,32 @@
import * as React from 'react'
import type { VersionInfo } from '../../../../../../server/dev/parse-version-info'
import { Dialog, DialogContent, DialogHeader } from '../components/Dialog'
import { Overlay } from '../components/Overlay'
import { VersionStalenessInfo } from '../components/VersionStalenessInfo'
import { useCallback } from 'react'
import { HotlinkedText } from '../components/hot-linked-text'
import { ErrorOverlayLayout } from '../components/ErrorOverlayLayout/ErrorOverlayLayout'

type RootLayoutMissingTagsErrorProps = {
missingTags: string[]
versionInfo?: VersionInfo
}

export const RootLayoutMissingTagsError: React.FC<RootLayoutMissingTagsErrorProps> =
function RootLayoutMissingTagsError({ missingTags, versionInfo }) {
const noop = React.useCallback(() => {}, [])
return (
<Overlay>
<Dialog
type="error"
aria-labelledby="nextjs__container_errors_label"
aria-describedby="nextjs__container_errors_desc"
onClose={noop}
>
<DialogContent>
<DialogHeader className="nextjs-container-errors-header">
<VersionStalenessInfo versionInfo={versionInfo} />
<h1
id="nextjs__container_errors_label"
className="nextjs__container_errors_label"
>
Missing required html tags
</h1>
<p
id="nextjs__container_errors_desc"
className="nextjs__container_errors_desc"
>
<HotlinkedText
text={`The following tags are missing in the Root Layout: ${missingTags
.map((tagName) => `<${tagName}>`)
.join(
', '
)}.\nRead more at https://nextjs.org/docs/messages/missing-root-layout-tags`}
/>
</p>
</DialogHeader>
</DialogContent>
</Dialog>
</Overlay>
)
}
export function RootLayoutMissingTagsError({
missingTags,
versionInfo,
}: RootLayoutMissingTagsErrorProps) {
const noop = useCallback(() => {}, [])
return (
<ErrorOverlayLayout
errorType="Missing Required HTML Tag"
errorMessage={
<HotlinkedText
text={`The following tags are missing in the Root Layout: ${missingTags
.map((tagName) => `<${tagName}>`)
.join(
', '
)}.\nRead more at https://nextjs.org/docs/messages/missing-root-layout-tags`}
/>
}
onClose={noop}
versionInfo={versionInfo}
/>
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { Base } from '../styles/Base'
import { CssReset } from '../styles/CssReset'
import { ComponentStyles } from '../styles/ComponentStyles'
import { ShadowPortal } from '../components/ShadowPortal'

export const withShadowPortal = (Story: any) => (
<ShadowPortal>
<CssReset />
<Base />
<ComponentStyles />
<Story />
</ShadowPortal>
)
19 changes: 19 additions & 0 deletions patches/@[email protected]
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
diff --git a/dist/types-a5624094.d.ts b/dist/types-a5624094.d.ts
index 8e1eb5e94642cb7e943fdb09da96606021701921..9958875a5d2026867455238ec44a71f905d758a4 100644
--- a/dist/types-a5624094.d.ts
+++ b/dist/types-a5624094.d.ts
@@ -1,4 +1,4 @@
-import { ComponentType } from 'react';
+import { ComponentType, JSX } from 'react';
import { WebRenderer, Canvas } from 'storybook/internal/types';

interface ReactRenderer extends WebRenderer {
diff --git a/template/components/index.js b/template/components/index.js
deleted file mode 100644
index c473ab7bed22857c051643fc4f0fce5637793adc..0000000000000000000000000000000000000000
diff --git a/template/stories/docgen-components/imported.js b/template/stories/docgen-components/imported.js
deleted file mode 100644
index bd94145261b03fff811e93a3d8f350a03b7a5105..0000000000000000000000000000000000000000
diff --git a/template/stories/docgen-components/js-proptypes/ext.js b/template/stories/docgen-components/js-proptypes/ext.js
deleted file mode 100644
index 11d0ad4810bb77980bc7be0b7697f3a85b15ffd2..0000000000000000000000000000000000000000
11 changes: 7 additions & 4 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading