Skip to content

Commit 2c7b3fa

Browse files
committed
[devtools] storybook: port utils to be reusable
1 parent 058d62c commit 2c7b3fa

File tree

5 files changed

+257
-245
lines changed

5 files changed

+257
-245
lines changed

packages/next/src/next-devtools/dev-overlay/container/errors.stories.tsx

Lines changed: 1 addition & 139 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@ import type { Meta, StoryObj } from '@storybook/react'
22

33
import { Errors } from './errors'
44
import { withShadowPortal } from '../storybook/with-shadow-portal'
5-
import type { ReadyRuntimeError } from '../utils/get-error-by-type'
65
import { lorem } from '../utils/lorem'
6+
import { runtimeErrors } from '../storybook/errors'
77

88
const meta: Meta<typeof Errors> = {
99
component: Errors,
@@ -16,144 +16,6 @@ const meta: Meta<typeof Errors> = {
1616
export default meta
1717
type Story = StoryObj<typeof Errors>
1818

19-
const originalCodeFrame = (message: string) => {
20-
return `\u001b[0m \u001b[90m 1 \u001b[39m \u001b[36mexport\u001b[39m \u001b[36mdefault\u001b[39m \u001b[36mfunction\u001b[39m \u001b[33mHome\u001b[39m() {\u001b[0m
21-
\u001b[0m\u001b[31m\u001b[1m>\u001b[22m\u001b[39m\u001b[90m 2 \u001b[39m \u001b[36mthrow\u001b[39m \u001b[36mnew\u001b[39m \u001b[33mError\u001b[39m(\u001b[32m'${message}'\u001b[39m)\u001b[0m
22-
\u001b[0m \u001b[90m \u001b[39m \u001b[31m\u001b[1m^\u001b[22m\u001b[39m\u001b[0m
23-
\u001b[0m \u001b[90m 3 \u001b[39m \u001b[36mreturn\u001b[39m \u001b[33m<\u001b[39m\u001b[33mdiv\u001b[39m\u001b[33m>\u001b[39m\u001b[33mWelcome to my Next.js application! This is a longer piece of text that will demonstrate text wrapping behavior in the code frame.\u001b[39m\u001b[33m<\u001b[39m\u001b[33m/\u001b[39m\u001b[33mdiv\u001b[39m\u001b[33m>\u001b[39m\u001b[0m
24-
\u001b[0m \u001b[90m 4 \u001b[39m }\u001b[0m
25-
\u001b[0m \u001b[90m 5 \u001b[39m\u001b[0m`
26-
}
27-
28-
const sourceStackFrame = {
29-
file: 'app/page.tsx',
30-
methodName: 'Home',
31-
arguments: [],
32-
lineNumber: 2,
33-
column: 9,
34-
}
35-
36-
const originalStackFrame = {
37-
file: 'app/page.tsx',
38-
methodName: 'Home',
39-
arguments: [],
40-
lineNumber: 2,
41-
column: 9,
42-
ignored: false,
43-
}
44-
45-
const frame = {
46-
originalStackFrame: {
47-
file: './app/page.tsx',
48-
methodName: 'MyComponent',
49-
arguments: [],
50-
lineNumber: 10,
51-
column: 5,
52-
ignored: false,
53-
},
54-
sourceStackFrame: {
55-
file: './app/page.tsx',
56-
methodName: 'MyComponent',
57-
arguments: [],
58-
lineNumber: 10,
59-
column: 5,
60-
},
61-
originalCodeFrame: 'export default function MyComponent() {',
62-
error: false,
63-
reason: null,
64-
external: false,
65-
ignored: false,
66-
}
67-
68-
const ignoredFrame = {
69-
...frame,
70-
ignored: true,
71-
}
72-
73-
const runtimeErrors: ReadyRuntimeError[] = [
74-
{
75-
id: 1,
76-
runtime: true,
77-
error: new Error('First error message'),
78-
frames: () =>
79-
Promise.resolve([
80-
frame,
81-
{
82-
...frame,
83-
originalStackFrame: {
84-
...frame.originalStackFrame,
85-
methodName: 'ParentComponent',
86-
lineNumber: 5,
87-
},
88-
},
89-
{
90-
...frame,
91-
originalStackFrame: {
92-
...frame.originalStackFrame,
93-
methodName: 'GrandparentComponent',
94-
lineNumber: 1,
95-
},
96-
},
97-
...Array(20).fill(ignoredFrame),
98-
]),
99-
type: 'runtime',
100-
},
101-
{
102-
id: 2,
103-
runtime: true,
104-
error: new Error('Second error message'),
105-
frames: () =>
106-
Promise.resolve([
107-
{
108-
error: true,
109-
reason: 'Second error message',
110-
external: false,
111-
ignored: false,
112-
sourceStackFrame,
113-
originalStackFrame,
114-
originalCodeFrame: originalCodeFrame('Second error message'),
115-
},
116-
]),
117-
type: 'runtime',
118-
},
119-
{
120-
id: 3,
121-
runtime: true,
122-
error: new Error('Third error message'),
123-
frames: () =>
124-
Promise.resolve([
125-
{
126-
error: true,
127-
reason: 'Third error message',
128-
external: false,
129-
ignored: false,
130-
sourceStackFrame,
131-
originalStackFrame,
132-
originalCodeFrame: originalCodeFrame('Third error message'),
133-
},
134-
]),
135-
type: 'runtime',
136-
},
137-
{
138-
id: 4,
139-
runtime: true,
140-
error: new Error('typeof window !== undefined'),
141-
frames: () =>
142-
Promise.resolve([
143-
{
144-
error: true,
145-
reason: 'typeof window !== undefined',
146-
external: false,
147-
ignored: false,
148-
sourceStackFrame,
149-
originalStackFrame,
150-
originalCodeFrame: originalCodeFrame('typeof window !== undefined'),
151-
},
152-
]),
153-
type: 'runtime',
154-
},
155-
]
156-
15719
export const Default: Story = {
15820
args: {
15921
getSquashedHydrationErrorDetails: () => null,

packages/next/src/next-devtools/dev-overlay/dev-overlay.stories.tsx

Lines changed: 12 additions & 105 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,15 @@
11
import type { Meta, StoryObj } from '@storybook/react'
2-
import type { DispatcherEvent, OverlayState } from './shared'
2+
import type { OverlayState } from './shared'
33

44
// @ts-expect-error
55
import imgApp from './app.png'
66

7-
import { useReducer } from 'react'
87
import { DevOverlay } from './dev-overlay'
8+
import { errors } from './storybook/errors'
99
import {
10-
ACTION_DEVTOOLS_POSITION,
11-
ACTION_DEVTOOLS_PANEL_CLOSE,
12-
ACTION_DEVTOOLS_PANEL_TOGGLE,
13-
ACTION_ERROR_OVERLAY_CLOSE,
14-
ACTION_ERROR_OVERLAY_OPEN,
15-
ACTION_ERROR_OVERLAY_TOGGLE,
16-
ACTION_DEVTOOLS_SCALE,
17-
NEXT_DEV_TOOLS_SCALE,
18-
INITIAL_OVERLAY_STATE,
19-
} from './shared'
10+
storybookDefaultOverlayState,
11+
useStorybookOverlayReducer,
12+
} from './storybook/use-overlay-reducer'
2013

2114
const meta: Meta<typeof DevOverlay> = {
2215
component: DevOverlay,
@@ -40,104 +33,18 @@ const meta: Meta<typeof DevOverlay> = {
4033
export default meta
4134
type Story = StoryObj<typeof DevOverlay>
4235

43-
const initialState: OverlayState = {
44-
...INITIAL_OVERLAY_STATE,
45-
routerType: 'app',
46-
showIndicator: true,
47-
errors: [
48-
{
49-
id: 1,
50-
error: Object.assign(new Error('First error message'), {
51-
__NEXT_ERROR_CODE: 'E001',
52-
}),
53-
componentStackFrames: [
54-
{
55-
file: 'app/page.tsx',
56-
component: 'Home',
57-
lineNumber: 10,
58-
column: 5,
59-
canOpenInEditor: true,
60-
},
61-
],
62-
frames: [
63-
{
64-
file: 'app/page.tsx',
65-
methodName: 'Home',
66-
arguments: [],
67-
lineNumber: 10,
68-
column: 5,
69-
},
70-
],
71-
type: 'runtime',
72-
},
73-
{
74-
id: 2,
75-
error: Object.assign(new Error('Second error message'), {
76-
__NEXT_ERROR_CODE: 'E002',
77-
}),
78-
frames: [],
79-
type: 'runtime',
80-
},
81-
{
82-
id: 3,
83-
error: Object.assign(new Error('Third error message'), {
84-
__NEXT_ERROR_CODE: 'E003',
85-
}),
86-
frames: [],
87-
type: 'runtime',
88-
},
89-
],
90-
versionInfo: {
91-
installed: '15.2.0',
92-
staleness: 'fresh',
93-
},
94-
isErrorOverlayOpen: false,
95-
isDevToolsPanelOpen: false,
96-
devToolsPosition: 'bottom-left',
97-
scale: NEXT_DEV_TOOLS_SCALE.Medium,
98-
}
99-
100-
function useOverlayReducer() {
101-
return useReducer<OverlayState, [DispatcherEvent]>(
102-
(state, action): OverlayState => {
103-
switch (action.type) {
104-
case ACTION_ERROR_OVERLAY_CLOSE: {
105-
return { ...state, isErrorOverlayOpen: false }
106-
}
107-
case ACTION_ERROR_OVERLAY_OPEN: {
108-
return { ...state, isErrorOverlayOpen: true }
109-
}
110-
case ACTION_ERROR_OVERLAY_TOGGLE: {
111-
return { ...state, isErrorOverlayOpen: !state.isErrorOverlayOpen }
112-
}
113-
case ACTION_DEVTOOLS_PANEL_TOGGLE: {
114-
return { ...state, isDevToolsPanelOpen: !state.isDevToolsPanelOpen }
115-
}
116-
case ACTION_DEVTOOLS_PANEL_CLOSE: {
117-
return { ...state, isDevToolsPanelOpen: false }
118-
}
119-
case ACTION_DEVTOOLS_POSITION: {
120-
return { ...state, devToolsPosition: action.devToolsPosition }
121-
}
122-
case ACTION_DEVTOOLS_SCALE: {
123-
return { ...state, scale: action.scale }
124-
}
125-
default: {
126-
return state
127-
}
128-
}
129-
},
130-
initialState
131-
)
132-
}
133-
13436
function getNoSquashedHydrationErrorDetails() {
13537
return null
13638
}
13739

40+
const initialState: OverlayState = {
41+
...storybookDefaultOverlayState,
42+
errors,
43+
}
44+
13845
export const Default: Story = {
13946
render: function DevOverlayStory() {
140-
const [state, dispatch] = useOverlayReducer()
47+
const [state, dispatch] = useStorybookOverlayReducer(initialState)
14148
return (
14249
<>
14350
<img
@@ -171,7 +78,7 @@ export const WithPanel: Story = {
17178
}
17279
},
17380
render: function DevOverlayStory() {
174-
const [state, dispatch] = useOverlayReducer()
81+
const [state, dispatch] = useStorybookOverlayReducer()
17582
return (
17683
<>
17784
<img

0 commit comments

Comments
 (0)