@@ -36,6 +36,7 @@ import type { ReadyRuntimeError } from '../../../../utils/get-error-by-type'
36
36
import { EnvironmentNameLabel } from '../environment-name-label/environment-name-label'
37
37
import { useFocusTrap } from '../dev-tools-indicator/utils'
38
38
import { Fader } from '../../fader'
39
+ import { Resizer } from '../../resizer'
39
40
40
41
export interface ErrorOverlayLayoutProps extends ErrorBaseProps {
41
42
errorMessage : ErrorMessageType
@@ -59,6 +60,7 @@ export function ErrorOverlayLayout({
59
60
errorType,
60
61
children,
61
62
errorCode,
63
+ errorCount,
62
64
error,
63
65
debugInfo,
64
66
isBuildError,
@@ -83,6 +85,10 @@ export function ErrorOverlayLayout({
83
85
} as React . CSSProperties ,
84
86
}
85
87
88
+ const [ animating , setAnimating ] = React . useState (
89
+ Boolean ( transitionDurationMs )
90
+ )
91
+
86
92
const faderRef = React . useRef < HTMLDivElement | null > ( null )
87
93
const hasFooter = Boolean ( footerMessage || errorCode )
88
94
const dialogRef = React . useRef < HTMLDivElement | null > ( null )
@@ -95,9 +101,23 @@ export function ErrorOverlayLayout({
95
101
}
96
102
}
97
103
104
+ function onTransitionEnd ( { propertyName, target } : React . TransitionEvent ) {
105
+ // We can only measure height after the `scale` transition ends,
106
+ // otherwise we will measure height as a multiple of the animating value
107
+ // which will give us an incorrect value.
108
+ if ( propertyName === 'scale' && target === dialogRef . current ) {
109
+ setAnimating ( false )
110
+ }
111
+ }
112
+
98
113
return (
99
114
< ErrorOverlayOverlay fixed = { isBuildError } { ...animationProps } >
100
- < div data-nextjs-dialog-root ref = { dialogRef } { ...animationProps } >
115
+ < div
116
+ data-nextjs-dialog-root
117
+ onTransitionEnd = { onTransitionEnd }
118
+ ref = { dialogRef }
119
+ { ...animationProps }
120
+ >
101
121
< ErrorOverlayNav
102
122
runtimeErrors = { runtimeErrors }
103
123
activeIdx = { activeIdx }
@@ -119,30 +139,37 @@ export function ErrorOverlayLayout({
119
139
)
120
140
}
121
141
>
122
- < DialogContent >
123
- < ErrorOverlayDialogHeader >
124
- < div
125
- className = "nextjs__container_errors__error_title"
126
- // allow assertion in tests before error rating is implemented
127
- data-nextjs-error-code = { errorCode }
128
- >
129
- < span data-nextjs-error-label-group >
130
- < ErrorTypeLabel errorType = { errorType } />
131
- { error . environmentName && (
132
- < EnvironmentNameLabel
133
- environmentName = { error . environmentName }
134
- />
135
- ) }
136
- </ span >
137
- < ErrorOverlayToolbar error = { error } debugInfo = { debugInfo } />
138
- </ div >
139
- < ErrorMessage errorMessage = { errorMessage } />
140
- </ ErrorOverlayDialogHeader >
142
+ < Resizer
143
+ ref = { dialogResizerRef }
144
+ measure = { ! animating }
145
+ data-nextjs-dialog-sizer
146
+ >
147
+ < DialogContent >
148
+ < ErrorOverlayDialogHeader >
149
+ < div
150
+ className = "nextjs__container_errors__error_title"
151
+ // allow assertion in tests before error rating is implemented
152
+ data-nextjs-error-code = { errorCode }
153
+ >
154
+ < span data-nextjs-error-label-group >
155
+ < ErrorTypeLabel errorType = { errorType } />
156
+ { error . environmentName && (
157
+ < EnvironmentNameLabel
158
+ environmentName = { error . environmentName }
159
+ />
160
+ ) }
161
+ </ span >
162
+ < ErrorOverlayToolbar error = { error } debugInfo = { debugInfo } />
163
+ </ div >
164
+ < ErrorMessage errorMessage = { errorMessage } />
165
+ </ ErrorOverlayDialogHeader >
166
+
167
+ < ErrorOverlayDialogBody > { children } </ ErrorOverlayDialogBody >
168
+ </ DialogContent >
169
+ </ Resizer >
141
170
142
- < ErrorOverlayDialogBody > { children } </ ErrorOverlayDialogBody >
143
- </ DialogContent >
144
171
< ErrorOverlayBottomStack
145
- errorCount = { runtimeErrors ?. length ?? 0 }
172
+ errorCount = { errorCount }
146
173
activeIdx = { activeIdx ?? 0 }
147
174
/>
148
175
</ ErrorOverlayDialog >
0 commit comments