@@ -17,8 +17,7 @@ interface ComponentPreviewProps {
1717}
1818
1919export const Preview = async ( { path, className } : ComponentPreviewProps ) => {
20- const rawCode = await readFile ( join ( process . cwd ( ) , 'components' , 'previews' , `${ path } .tsx` ) , 'utf-8' ) ;
21- const code = extractPreviewSnippet ( rawCode ) ;
20+ const code = await readFile ( join ( process . cwd ( ) , 'components' , 'previews' , `${ path } .tsx` ) , 'utf-8' ) ;
2221
2322 const highlightedCode = await codeToHtml ( code , {
2423 lang : 'tsx' ,
@@ -54,116 +53,3 @@ export const Preview = async ({ path, className }: ComponentPreviewProps) => {
5453 </ CodeBlockTabs >
5554 ) ;
5655} ;
57-
58- const extractPreviewSnippet = ( rawCode : string ) => {
59- const withoutUseClient = rawCode . replace ( / ^ \s * [ ' " ] u s e c l i e n t [ ' " ] ; ? \s * \n + / m, '' ) ;
60- const importLines = withoutUseClient
61- . split ( '\n' )
62- . filter ( ( line ) => line . trim ( ) . startsWith ( 'import ' ) )
63- . join ( '\n' )
64- . trim ( ) ;
65-
66- const multilineMatch = withoutUseClient . match ( / = > \s * \( ( [ \s \S ] * ?) \) ; \s * e x p o r t \s + d e f a u l t / s) ;
67- const singleLineMatch = withoutUseClient . match ( / = > \s * ( [ ^ \n ; ] + ) ; \s * e x p o r t \s + d e f a u l t / s) ;
68- const rawBody = multilineMatch ?. [ 1 ] ?? singleLineMatch ?. [ 1 ] ?? '' ;
69- const body = sanitizeSnippet ( dedentSnippet ( rawBody ) ) ;
70- const helpers = sanitizeSnippet ( dedentSnippet ( extractHelperCode ( withoutUseClient ) ) ) ;
71-
72- if ( ! importLines && ! body ) {
73- return withoutUseClient . trim ( ) ;
74- }
75-
76- return [ importLines , helpers , body ] . filter ( Boolean ) . join ( '\n\n' ) ;
77- } ;
78-
79- const dedentSnippet = ( snippet : string ) => {
80- if ( ! snippet ) {
81- return snippet ;
82- }
83-
84- const allLines = snippet . split ( '\n' ) ;
85- let start = 0 ;
86- let end = allLines . length ;
87-
88- while ( start < end && allLines [ start ] . trim ( ) . length === 0 ) {
89- start += 1 ;
90- }
91-
92- while ( end > start && allLines [ end - 1 ] . trim ( ) . length === 0 ) {
93- end -= 1 ;
94- }
95-
96- const lines = allLines . slice ( start , end ) ;
97- const nonEmptyLines = lines . filter ( ( line ) => line . trim ( ) . length > 0 ) ;
98- const minIndent = nonEmptyLines . reduce ( ( min , line ) => {
99- const match = line . match ( / ^ ( \s + ) / ) ;
100- if ( ! match ) {
101- return 0 ;
102- }
103- return Math . min ( min , match [ 1 ] . length ) ;
104- } , Number . POSITIVE_INFINITY ) ;
105-
106- if ( ! Number . isFinite ( minIndent ) || minIndent === 0 ) {
107- return snippet ;
108- }
109-
110- return lines . map ( ( line ) => ( line . trim ( ) . length ? line . slice ( minIndent ) : line ) ) . join ( '\n' ) ;
111- } ;
112-
113- const sanitizeSnippet = ( snippet : string ) => {
114- let cleaned = snippet ;
115-
116- cleaned = cleaned . replace ( / ^ \s * d e f a u l t O p e n \s * \n / gm, '' ) ;
117- cleaned = cleaned . replace ( / ^ \s * r e u s e C o n t e x t = \{ f a l s e \} \s * \n / gm, '' ) ;
118- cleaned = cleaned . replace ( / ^ \s * p e r s i s t e n c e = \{ \{ \s * k e y : \s * ' d o c s - p r e v i e w ' \s * \} \} \s * \n / gm, '' ) ;
119-
120- cleaned = cleaned . replace ( / \s + d e f a u l t O p e n \b / g, '' ) ;
121- cleaned = cleaned . replace ( / \s + r e u s e C o n t e x t = \{ f a l s e \} / g, '' ) ;
122- cleaned = cleaned . replace ( / \s + p e r s i s t e n c e = \{ \{ \s * k e y : \s * ' d o c s - p r e v i e w ' \s * \} \} / g, '' ) ;
123-
124- cleaned = cleaned . replace ( / < ( [ ^ > ] * ?) \s + > / g, '<$1>' ) ;
125- cleaned = cleaned . replace ( / < ( [ ^ > ] * ?) \s + \/ > / g, '<$1 />' ) ;
126-
127- return cleaned ;
128- } ;
129-
130- const extractHelperCode = ( rawCode : string ) => {
131- const exportMatch = rawCode . match ( / e x p o r t \s + d e f a u l t \s + ( \w + ) / ) ;
132- const exportName = exportMatch ?. [ 1 ] ;
133- let content = rawCode ;
134-
135- if ( exportName ) {
136- const safeExportName = exportName . replace ( / [ . * + ? ^ $ { } ( ) | [ \] \\ ] / g, '\\$&' ) ;
137- content = content . replace ( new RegExp ( `export\\s+default\\s+${ safeExportName } ;?\\s*` , 'g' ) , '' ) ;
138- content = removeExportedComponent ( content , exportName ) ;
139- content = content . replace (
140- new RegExp ( `function\\s+${ safeExportName } \\s*\\([\\s\\S]*?\\)\\s*\\{[\\s\\S]*?\\}\\s*` , 'm' ) ,
141- ''
142- ) ;
143- }
144-
145- const withoutImports = content
146- . split ( '\n' )
147- . filter ( ( line ) => ! line . trim ( ) . startsWith ( 'import ' ) )
148- . join ( '\n' )
149- . trim ( ) ;
150-
151- return withoutImports ;
152- } ;
153-
154- const removeExportedComponent = ( source : string , exportName : string ) => {
155- const pattern = `const ${ exportName } ` ;
156- const startIndex = source . indexOf ( pattern ) ;
157- if ( startIndex === - 1 ) {
158- return source ;
159- }
160-
161- const afterStart = source . slice ( startIndex ) ;
162- const endIndex = afterStart . indexOf ( ');' ) ;
163- if ( endIndex === - 1 ) {
164- return source ;
165- }
166-
167- const removeLength = endIndex + 2 ;
168- return source . slice ( 0 , startIndex ) + afterStart . slice ( removeLength ) ;
169- } ;
0 commit comments