@@ -48,41 +48,90 @@ const decodeHTML = (str) => {
48
48
. replace ( / & # 0 3 9 ; / g, "'" ) ;
49
49
} ;
50
50
51
- const htmlWrapper = ( htmlString , layout ) => {
52
- return `<!DOCTYPE html><html><head><style>html, body {height:100%} body {box-sizing: border-box; margin: 0; padding:0.5rem; ${ layout } }</style><script src="https://cdn.shopify.com/shopifycloud/polaris.js"></script></head><body>${ decodeHTML (
51
+ const composeStyles = ( ...styles ) => {
52
+ return styles
53
+ . filter ( Boolean )
54
+ . map ( ( style ) => style . trim ( ) )
55
+ . filter ( ( style ) => style . length > 0 )
56
+ . join ( ' ' ) ;
57
+ } ;
58
+
59
+ // Don't allow all CSS properties to be used in the customStyles property
60
+ // DO NOT ADD MORE PROPERTIES TO THIS LIST
61
+ const allowedProperties = [ 'minHeight' , 'minBlockSize' ] ;
62
+
63
+ const stylesToString = ( styles ) => {
64
+ if ( ! styles ) return '' ;
65
+ return Object . entries ( styles )
66
+ . filter (
67
+ ( [ property , value ] ) =>
68
+ allowedProperties . includes ( property ) &&
69
+ value !== undefined &&
70
+ value !== null ,
71
+ )
72
+ . map ( ( [ property , value ] ) => {
73
+ const kebabProperty = property . replace (
74
+ / [ A - Z ] / g,
75
+ ( match ) => `-${ match . toLowerCase ( ) } ` ,
76
+ ) ;
77
+ return `${ kebabProperty } : ${ value } ` ;
78
+ } )
79
+ . join ( '; ' ) ;
80
+ } ;
81
+
82
+ const htmlWrapper = ( htmlString , layoutStyles = '' , customStyles = '' ) => {
83
+ const baseStyles = 'box-sizing: border-box; margin: 0; padding: 0.5rem;' ;
84
+ const composedStyles = composeStyles ( baseStyles , layoutStyles , customStyles ) ;
85
+
86
+ return `<!DOCTYPE html><html><head><style>html, body {height:100%} body {${ composedStyles } }</style><script src="https://cdn.shopify.com/shopifycloud/polaris.js"></script></head><body>${ decodeHTML (
53
87
htmlString ,
54
88
) } </body></html>`;
55
89
} ;
56
90
91
+ const createTemplate = ( {
92
+ layoutStyles,
93
+ wrapperElement = null ,
94
+ wrapperAttributes = '' ,
95
+ } ) => {
96
+ return ( htmlString , customStyles ) => {
97
+ const wrappedHtml = wrapperElement
98
+ ? `<${ wrapperElement } ${
99
+ wrapperAttributes ? ` ${ wrapperAttributes } ` : ''
100
+ } >${ htmlString } </${ wrapperElement } >`
101
+ : htmlString ;
102
+ const customStylesString = stylesToString ( customStyles ) ;
103
+
104
+ return htmlWrapper ( wrappedHtml , layoutStyles , customStylesString ) ;
105
+ } ;
106
+ } ;
107
+
57
108
const templates = {
58
- default : ( htmlString ) =>
59
- htmlWrapper ( htmlString , 'display: grid; place-items: center; gap: 0.5rem;' ) ,
60
- alignStart : ( htmlString ) =>
61
- htmlWrapper (
62
- `<div>${ htmlString } </div>` ,
63
- 'display: grid; place-items: start center; gap: 0.5rem;' ,
64
- ) ,
65
- wrapped : ( htmlString ) =>
66
- htmlWrapper (
67
- `<div>${ htmlString } </div>` ,
68
- 'display: grid; place-items: center; gap: 0.5rem;' ,
69
- ) ,
70
- inline : ( htmlString ) =>
71
- htmlWrapper (
72
- htmlString ,
109
+ default : createTemplate ( {
110
+ layoutStyles : 'display: grid; place-items: center; gap: 0.5rem;' ,
111
+ } ) ,
112
+ alignStart : createTemplate ( {
113
+ layoutStyles : 'display: grid; place-items: start center; gap: 0.5rem;' ,
114
+ wrapperElement : 'div' ,
115
+ } ) ,
116
+ wrapped : createTemplate ( {
117
+ layoutStyles : 'display: grid; place-items: center; gap: 0.5rem;' ,
118
+ wrapperElement : 'div' ,
119
+ } ) ,
120
+ inline : createTemplate ( {
121
+ layoutStyles :
73
122
'display: flex; justify-content: center; align-items: center; gap: 0.5rem;' ,
74
- ) ,
75
- section : ( htmlString ) =>
76
- htmlWrapper (
77
- `< s-section padding="none"> ${ htmlString } </s-section>` ,
78
- 'display: grid; place-items: center; background: #F1F1F1 ',
79
- ) ,
80
- page : ( htmlString ) =>
81
- htmlWrapper (
82
- htmlString ,
83
- 'display: grid; place-items: center; background: #F1F1F1;' ,
84
- ) ,
85
- none : ( htmlString ) => htmlWrapper ( htmlString , 'padding: 0' ) ,
123
+ } ) ,
124
+ section : createTemplate ( {
125
+ layoutStyles : 'display: grid; place-items: center; background: #F1F1F1' ,
126
+ wrapperElement : ' s-section' ,
127
+ wrapperAttributes : 'padding="none" ',
128
+ } ) ,
129
+ page : createTemplate ( {
130
+ layoutStyles : 'display: grid; place-items: center; background: #F1F1F1;' ,
131
+ } ) ,
132
+ none : createTemplate ( {
133
+ layoutStyles : 'padding: 0;' ,
134
+ } ) ,
86
135
} ;
87
136
88
137
const transformJson = async ( filePath , isExtensions ) => {
@@ -124,8 +173,8 @@ const transformJson = async (filePath, isExtensions) => {
124
173
125
174
const previewHTML =
126
175
tab . layout && tab . layout in templates
127
- ? templates [ tab . layout ] ( tab . code )
128
- : templates . default ( tab . code ) ;
176
+ ? templates [ tab . layout ] ( tab . code , tab . customStyles )
177
+ : templates . default ( tab . code , tab . customStyles ) ;
129
178
130
179
newTabs . push (
131
180
{ code : tab . code , language : 'html' } ,
0 commit comments