1
- import { Suspense , useState } from 'react'
1
+ import { createContext , Suspense , useContext , useMemo , useState } from 'react'
2
2
import { ErrorBoundary } from 'react-error-boundary'
3
3
import { useIsomorphicLayoutEffect } from 'framer-motion'
4
4
import type { FC } from 'react'
@@ -7,64 +7,92 @@ import { BlockLoading } from '~/components/modules/shared/BlockLoading'
7
7
import { loadScript } from '~/lib/load-script'
8
8
import { get } from '~/lib/lodash'
9
9
10
+ const StyleContext = createContext < React . CSSProperties > ( { } )
11
+
10
12
export interface ReactComponentRenderProps {
11
13
dls : string
12
14
}
15
+
13
16
/**
14
17
* define the render dls of the component
15
18
* ```component
16
19
* import=http://127.0.0.1:2333/snippets/js/components.js
17
20
* name=Components.Card
21
+ * height=20 // This is optional
18
22
* ```
19
23
*
20
24
* name will be used to find the component in the import, if in the nested object, use dot to separate
21
25
*
22
26
*/
23
27
export const ReactComponentRender : FC < ReactComponentRenderProps > = ( props ) => {
24
28
const { dls } = props
29
+ const dlsProps = parseDlsContent ( dls )
30
+ const style : React . CSSProperties = useMemo ( ( ) => {
31
+ if ( ! dlsProps . height ) return { }
32
+ const isNumberString = / ^ \d + $ / . test ( dlsProps . height )
33
+ return {
34
+ height : isNumberString ? `${ dlsProps . height } px` : dlsProps . height ,
35
+ }
36
+ } , [ dlsProps . height ] )
37
+ return (
38
+ < ErrorBoundary fallback = { < ComponentBlockError style = { style } /> } >
39
+ < StyleContext . Provider value = { style } >
40
+ < ReactComponentRenderImpl { ...dlsProps } />
41
+ </ StyleContext . Provider >
42
+ </ ErrorBoundary >
43
+ )
44
+ }
45
+ const ReactComponentRenderImpl : FC < DlsProps > = ( dlsProps ) => {
25
46
const [ Component , setComponent ] = useState ( {
26
47
component : ComponentBlockLoading ,
27
48
} )
28
49
50
+ const style = useContext ( StyleContext )
29
51
useIsomorphicLayoutEffect ( ( ) => {
30
- const props = parseDlsContent ( dls )
31
-
32
52
loadScript (
33
53
'https://unpkg.com/styled-components/dist/styled-components.min.js' ,
34
54
)
35
- . then ( ( ) => loadScript ( props . import ) )
55
+ . then ( ( ) => loadScript ( dlsProps . import ) )
36
56
. then ( ( ) => {
37
- const Component = get ( window , props . name )
57
+ const Component = get ( window , dlsProps . name )
38
58
console . log ( 'Component' , Component )
39
59
setComponent ( { component : Component } )
40
60
} )
41
- } , [ dls ] )
61
+ } , [ dlsProps ] )
42
62
43
63
return (
44
- < ErrorBoundary FallbackComponent = { ComponentBlockError } >
45
- < Suspense fallback = { < ComponentBlockLoading /> } >
46
- < Component . component />
64
+ < ErrorBoundary fallback = { < ComponentBlockError style = { style } /> } >
65
+ < Suspense fallback = { < ComponentBlockLoading style = { style } /> } >
66
+ < div style = { style } className = "overflow-hidden" >
67
+ < Component . component />
68
+ </ div >
47
69
</ Suspense >
48
70
</ ErrorBoundary >
49
71
)
50
72
}
51
73
52
- const ComponentBlockError = ( ) => {
74
+ const ComponentBlockError : FC < {
75
+ style ?: React . CSSProperties
76
+ } > = ( { style } ) => {
53
77
return (
54
- < BlockLoading className = "bg-red-300 dark:bg-red-700" >
78
+ < BlockLoading style = { style } className = "bg-red-300 dark:bg-red-700" >
55
79
Component Error
56
80
</ BlockLoading >
57
81
)
58
82
}
59
- const ComponentBlockLoading = ( ) => {
60
- return < BlockLoading > Component Loading...</ BlockLoading >
83
+ const ComponentBlockLoading : FC < {
84
+ style ?: React . CSSProperties
85
+ } > = ( { style } ) => {
86
+ return < BlockLoading style = { style } > Component Loading...</ BlockLoading >
61
87
}
62
88
89
+ type DlsProps = {
90
+ name : string
91
+ import : string
92
+ height ?: string
93
+ }
63
94
function parseDlsContent ( dls : string ) {
64
- const parsedProps = { } as {
65
- name : string
66
- import : string
67
- }
95
+ const parsedProps = { } as DlsProps
68
96
dls . split ( '\n' ) . forEach ( ( line ) => {
69
97
const [ key , value ] = line . split ( '=' )
70
98
; ( parsedProps as any ) [ key ] = value
0 commit comments