11import * as React from "react" ;
22import * as runtime from "react/jsx-runtime" ;
3+ import * as R from "remeda" ;
34
45import { evaluate , EvaluateOptions } from "@mdx-js/mdx" ;
5- import { CircularProgress , Typography } from "@mui/material" ;
6+ import { Button , CircularProgress , Typography } from "@mui/material" ;
67import { ErrorBoundary , Suspense } from "@suspensive/react" ;
78import { useSuspenseQuery } from "@tanstack/react-query" ;
89import components , { MuiMdxComponentsOptions } from 'mui-mdx-components' ;
9- import * as R from "remeda" ;
1010
1111import { useCommonContext } from '../hooks/useCommonContext' ;
1212
@@ -26,11 +26,45 @@ const MDXComponents: MuiMdxComponentsOptions = {
2626 }
2727}
2828
29- const useMDX = ( text : string ) => {
30- const { baseUrl } = useCommonContext ( ) ;
31- const options : EvaluateOptions = { ...runtime , baseUrl }
29+ const SimplifiedMDXErrorFallback : React . FC < { reset : ( ) => void } > = ( { reset } ) => {
30+ return < >
31+ < Typography variant = "body2" color = "error" >
32+ 페이지를 그리던 중 문제가 발생했습니다, 잠시 후 다시 시도해주세요.< br />
33+ 만약 문제가 계속 발생한다면, 파이콘 한국 준비 위원회에게 알려주세요!< br />
34+ < br />
35+ Problem occurred while drawing the page, please try again later.< br />
36+ If the problem persists, please let the PyCon Korea organizing committee know!
37+ </ Typography >
38+ < br />
39+ < Button variant = "outlined" onClick = { reset } > 다시 시도 | Retry</ Button >
40+ </ > ;
41+ }
42+
43+ const DetailedMDXErrorFallback : React . FC < { error : Error , reset : ( ) => void } > = ( { error, reset } ) => {
44+ const errorObject = Object . getOwnPropertyNames ( error ) . reduce ( ( acc , key ) => ( { ...acc , [ key ] : ( error as unknown as { [ key : string ] : unknown } ) [ key ] } ) , { } ) ;
45+ return < >
46+ < Typography variant = "body2" color = "error" > MDX 변환 오류: { error . message } </ Typography >
47+ < details open >
48+ < summary > 오류 상세</ summary >
49+ < pre style = { {
50+ whiteSpace : "pre-wrap" ,
51+ backgroundColor : "#f5f5f5" ,
52+ padding : "1em" ,
53+ borderRadius : "4px" ,
54+ userSelect : "text" ,
55+ } } >
56+ < code > { JSON . stringify ( errorObject , null , 2 ) } </ code >
57+ </ pre >
58+ </ details >
59+ < br />
60+ < Button variant = "outlined" onClick = { reset } > 다시 시도</ Button >
61+ </ > ;
62+ } ;
63+
64+ const InnerMDXRenderer : React . FC < { text : string , baseUrl : string } > = ( { text, baseUrl } ) => {
65+ const options : EvaluateOptions = { ...runtime , baseUrl } ;
3266
33- return useSuspenseQuery ( {
67+ const { data } = useSuspenseQuery ( {
3468 queryKey : [ "mdx" , text ] ,
3569 queryFn : async ( ) => {
3670 const { default : RenderResult } = await evaluate ( text , options ) ;
@@ -39,30 +73,21 @@ const useMDX = (text: string) => {
3973 </ div >
4074 } ,
4175 } ) ;
42- }
4376
44- const MDXErrorFallback : React . FC < { error : Error } > = ( { error } ) => {
45- console . error ( error ) ;
46- return (
47- < Typography variant = "body2" color = "error" >
48- MDX 변환 오류: { error . message }
49- </ Typography >
50- ) ;
51- } ;
52-
53- const InnerMDXRenderer : React . FC < { text : string } > = ( { text } ) => {
54- const { data } = useMDX ( text ) ;
5577 return < > { data } </ > ;
5678}
5779
5880export const MDXRenderer : React . FC < { text : string } > = ( { text } ) => {
5981 // 원래 MDX는 각 줄의 마지막에 공백 2개가 있어야 줄바꿈이 되고, 또 연속 줄바꿈은 무시되지만,
6082 // 편의성을 위해 렌더러 단에서 공백 2개를 추가하고 연속 줄바꿈을 <br />로 변환합니다.
61- let processedText = text . split ( "\n" ) . map ( ( line ) => R . isEmpty ( line . trim ( ) ) ? "" : `${ line . trim ( ) } ` ) . join ( "\n" ) . replaceAll ( "\n\n" , "\n<br />\n" ) ;
83+ const { baseUrl, debug } = useCommonContext ( ) ;
84+
85+ const ErrorHandler = debug ? DetailedMDXErrorFallback : SimplifiedMDXErrorFallback ;
86+ const processedText = text . split ( "\n" ) . map ( ( line ) => R . isEmpty ( line . trim ( ) ) ? "" : `${ line . trim ( ) } ` ) . join ( "\n" ) . replaceAll ( "\n\n" , "\n<br />\n" ) ;
6287
63- return < ErrorBoundary fallback = { MDXErrorFallback } >
88+ return < ErrorBoundary fallback = { ErrorHandler } >
6489 < Suspense fallback = { < CircularProgress /> } >
65- < InnerMDXRenderer text = { processedText } />
90+ < InnerMDXRenderer text = { processedText } baseUrl = { baseUrl } />
6691 </ Suspense >
6792 </ ErrorBoundary >
6893} ;
0 commit comments