1
1
import { Button } from "@/components/Button" ;
2
2
import { ResizablePanel } from "@/components/Resizable" ;
3
+ import { useTheme } from "@/contexts/theme" ;
3
4
import {
4
5
type Diagnostic ,
5
6
type InternalDiagnostic ,
@@ -10,7 +11,8 @@ import { useDebouncedValue } from "@/hooks/debounce";
10
11
import { useStore } from "@/store" ;
11
12
import { cn } from "@/utils/cn" ;
12
13
import { ActivityIcon , ExternalLinkIcon , LoaderIcon } from "lucide-react" ;
13
- import { type FC , useEffect , useState } from "react" ;
14
+ import { AnimatePresence , motion } from "motion/react" ;
15
+ import { type FC , useEffect , useMemo , useState } from "react" ;
14
16
15
17
export const Preview : FC = ( ) => {
16
18
const $wasmState = useStore ( ( state ) => state . wasmState ) ;
@@ -183,60 +185,75 @@ const ErrorPane = () => {
183
185
const $errors = useStore ( ( state ) => state . errors ) ;
184
186
const $toggleShowError = useStore ( ( state ) => state . toggleShowError ) ;
185
187
186
- if ( $errors . diagnostics . length === 0 ) {
187
- return null ;
188
- }
188
+ const hasErrors = useMemo ( ( ) => $errors . diagnostics . length > 0 , [ $errors ] ) ;
189
189
190
190
return (
191
191
< >
192
- { /*
193
- * biome-ignore lint/a11y/useKeyWithClickEvents: key events don't seem to
194
- * work for divs, and I'm otherwise not sure how to make this element
195
- * more accesible. But I think it's fine since the functionality is able to
196
- * be used with the button.
197
- */ }
198
- < div
199
- aria-hidden = { true }
200
- className = { cn (
201
- "absolute top-0 left-0 hidden h-full w-full transition-all" ,
202
- $errors . show && "block cursor-pointer bg-black/10 dark:bg-black/50" ,
203
- ) }
204
- onClick = { ( ) => {
205
- $toggleShowError ( false ) ;
206
- } }
207
- >
208
- { /* OVERLAY */ }
209
- </ div >
192
+ < AnimatePresence propagate = { true } >
193
+ { $errors . show && hasErrors ? (
194
+ // lint/a11y/useKeyWithClickEvents: key events don't seem to
195
+ // work for divs, and I'm otherwise not sure how to make this element
196
+ // more accesible. But I think it's fine since the functionality is able to
197
+ // be used with the button below.
198
+ < motion . div
199
+ initial = { { opacity : 0 } }
200
+ animate = { { opacity : 1 } }
201
+ exit = { { opacity : 0 } }
202
+ aria-hidden = { true }
203
+ className = "absolute top-0 left-0 h-full w-full cursor-pointer bg-black/10 dark:bg-black/50"
204
+ onClick = { ( ) => {
205
+ $toggleShowError ( false ) ;
206
+ } }
207
+ >
208
+ { /* OVERLAY */ }
209
+ </ motion . div >
210
+ ) : null }
211
+ </ AnimatePresence >
210
212
211
- < div
212
- role = "alertdialog"
213
- className = { cn (
214
- "absolute bottom-0 left-0 flex max-h-[60%] w-full flex-col justify-start" ,
215
- $errors . show && "h-auto" ,
216
- ) }
217
- >
218
- < button
219
- className = "flex h-4 min-h-4 w-full items-center justify-center rounded-t-xl bg-border-destructive"
220
- onClick = { ( ) => $toggleShowError ( ) }
221
- aria-label = { $errors . show ? "Hide error dialog" : "Show error dialog" }
222
- >
223
- < div className = "h-0.5 w-2/3 max-w-32 rounded-full bg-white/40" > </ div >
224
- </ button >
213
+ < AnimatePresence propagate = { true } >
214
+ { hasErrors ? (
215
+ < motion . div
216
+ role = "alertdialog"
217
+ transition = { {
218
+ when : "afterChildren" ,
219
+ } }
220
+ exit = { { opacity : 0 } }
221
+ className = { cn (
222
+ "absolute bottom-0 left-0 flex max-h-[60%] w-full flex-col justify-start" ,
223
+ $errors . show && "h-auto" ,
224
+ ) }
225
+ >
226
+ < motion . button
227
+ className = "flex h-4 min-h-4 w-full items-center justify-center rounded-t-xl bg-border-destructive"
228
+ onClick = { ( ) => $toggleShowError ( ) }
229
+ aria-label = {
230
+ $errors . show ? "Hide error dialog" : "Show error dialog"
231
+ }
232
+ >
233
+ < div className = "h-0.5 w-2/3 max-w-32 rounded-full bg-white/40" > </ div >
234
+ </ motion . button >
225
235
226
- < div
227
- aria-hidden = { ! $errors . show }
228
- className = { cn (
229
- "flex flex-col gap-6 overflow-y-scroll bg-surface-secondary p-6" ,
230
- ! $errors . show && "pointer-events-none h-0 p-0" ,
231
- ) }
232
- >
233
- < div className = "flex w-full flex-col gap-3" >
234
- { $errors . diagnostics . map ( ( diagnostic , index ) => (
235
- < ErrorBlock diagnostic = { diagnostic } key = { index } />
236
- ) ) }
237
- </ div >
238
- </ div >
239
- </ div >
236
+ < AnimatePresence propagate = { true } >
237
+ { $errors . show ? (
238
+ < motion . div
239
+ initial = { { height : 0 } }
240
+ animate = { {
241
+ height : "auto" ,
242
+ } }
243
+ exit = { { height : 0 } }
244
+ className = "flex flex-col gap-6 overflow-y-scroll bg-surface-secondary"
245
+ >
246
+ < div className = "flex w-full flex-col gap-3 p-6" >
247
+ { $errors . diagnostics . map ( ( diagnostic , index ) => (
248
+ < ErrorBlock diagnostic = { diagnostic } key = { index } />
249
+ ) ) }
250
+ </ div >
251
+ </ motion . div >
252
+ ) : null }
253
+ </ AnimatePresence >
254
+ </ motion . div >
255
+ ) : null }
256
+ </ AnimatePresence >
240
257
</ >
241
258
) ;
242
259
} ;
0 commit comments