@@ -28,6 +28,8 @@ export const defaultPluginSettings: PluginSettings = {
2828 roundTailwindValues : false ,
2929 roundTailwindColors : false ,
3030 customTailwindColors : false ,
31+ customTailwindPrefix : "" ,
32+ embedImages : false ,
3133} ;
3234
3335// A helper type guard to ensure the key belongs to the PluginSettings type
@@ -63,14 +65,23 @@ const initSettings = async () => {
6365 safeRun ( userPluginSettings ) ;
6466} ;
6567
66- const safeRun = ( settings : PluginSettings ) => {
67- try {
68- run ( settings ) ;
69- } catch ( e ) {
70- if ( e && typeof e === "object" && "message" in e ) {
71- const error = e as Error ;
72- console . log ( "error: " , error . stack ) ;
73- figma . ui . postMessage ( { type : "error" , error : error . message } ) ;
68+ // Used to prevent running from happening again.
69+ let isLoading = false ;
70+ const safeRun = async ( settings : PluginSettings ) => {
71+ if ( isLoading === false ) {
72+ try {
73+ isLoading = true ;
74+ await run ( settings ) ;
75+ // hack to make it not immediately set to false when complete. (executes on next frame)
76+ setTimeout ( ( ) => {
77+ isLoading = false ;
78+ } , 1 ) ;
79+ } catch ( e ) {
80+ if ( e && typeof e === "object" && "message" in e ) {
81+ const error = e as Error ;
82+ console . log ( "error: " , error . stack ) ;
83+ figma . ui . postMessage ( { type : "error" , error : error . message } ) ;
84+ }
7485 }
7586 }
7687} ;
@@ -86,6 +97,10 @@ const standardMode = async () => {
8697
8798 // Listen for document changes
8899 figma . on ( "documentchange" , ( ) => {
100+ // Node: This was causing an infinite load when you try to export a background image from a group that contains children.
101+ // The reason for this is that the code will temporarily hide the children of the group in order to export a clean image
102+ // then restores the visibility of the children. This constitutes a document change so it's restarting the whole conversion.
103+ // In order to stop this, we disable safeRun() when doing conversions (while isLoading === true).
89104 safeRun ( userPluginSettings ) ;
90105 } ) ;
91106
@@ -105,121 +120,124 @@ const codegenMode = async () => {
105120 // figma.showUI(__html__, { visible: false });
106121 await getUserSettings ( ) ;
107122
108- figma . codegen . on ( "generate" , async ( { language, node } : CodegenEvent ) : Promise < CodegenResult [ ] > => {
109- const convertedSelection = convertIntoNodes ( [ node ] , null ) ;
110-
111- switch ( language ) {
112- case "html" :
113- return [
114- {
115- title : "Code" ,
116- code : await htmlMain (
117- convertedSelection ,
118- { ...userPluginSettings , jsx : false } ,
119- true ,
120- ) ,
121- language : "HTML" ,
122- } ,
123- {
124- title : "Text Styles" ,
125- code : htmlCodeGenTextStyles ( userPluginSettings ) ,
126- language : "HTML" ,
127- } ,
128- ] ;
129- case "html_jsx" :
130- return [
131- {
132- title : "Code" ,
133- code : await htmlMain (
134- convertedSelection ,
135- { ...userPluginSettings , jsx : true } ,
136- true ,
137- ) ,
138- language : "HTML" ,
139- } ,
140- {
141- title : "Text Styles" ,
142- code : htmlCodeGenTextStyles ( userPluginSettings ) ,
143- language : "HTML" ,
144- } ,
145- ] ;
146- case "tailwind" :
147- case "tailwind_jsx" :
148- return [
149- {
150- title : "Code" ,
151- code : await tailwindMain ( convertedSelection , {
152- ...userPluginSettings ,
153- jsx : language === "tailwind_jsx" ,
154- } ) ,
155- language : "HTML" ,
156- } ,
157- // {
158- // title: "Style",
159- // code: tailwindMain(convertedSelection, defaultPluginSettings),
160- // language: "HTML",
161- // },
162- {
163- title : "Tailwind Colors" ,
164- code : retrieveGenericSolidUIColors ( "Tailwind" )
165- . map ( ( d ) => {
166- let str = `${ d . hex } ;` ;
167- if ( d . colorName !== d . hex ) {
168- str += ` // ${ d . colorName } ` ;
169- }
170- if ( d . meta ) {
171- str += ` (${ d . meta } )` ;
172- }
173- return str ;
174- } )
175- . join ( "\n" ) ,
176- language : "JAVASCRIPT" ,
177- } ,
178- {
179- title : "Text Styles" ,
180- code : tailwindCodeGenTextStyles ( ) ,
181- language : "HTML" ,
182- } ,
183- ] ;
184- case "flutter" :
185- return [
186- {
187- title : "Code" ,
188- code : flutterMain ( convertedSelection , {
189- ...userPluginSettings ,
190- flutterGenerationMode : "snippet" ,
191- } ) ,
192- language : "SWIFT" ,
193- } ,
194- {
195- title : "Text Styles" ,
196- code : flutterCodeGenTextStyles ( ) ,
197- language : "SWIFT" ,
198- } ,
199- ] ;
200- case "swiftUI" :
201- return [
202- {
203- title : "SwiftUI" ,
204- code : swiftuiMain ( convertedSelection , {
205- ...userPluginSettings ,
206- swiftUIGenerationMode : "snippet" ,
207- } ) ,
208- language : "SWIFT" ,
209- } ,
210- {
211- title : "Text Styles" ,
212- code : swiftUICodeGenTextStyles ( ) ,
213- language : "SWIFT" ,
214- } ,
215- ] ;
216- default :
217- break ;
218- }
123+ figma . codegen . on (
124+ "generate" ,
125+ async ( { language, node } : CodegenEvent ) : Promise < CodegenResult [ ] > => {
126+ const convertedSelection = convertIntoNodes ( [ node ] , null ) ;
127+
128+ switch ( language ) {
129+ case "html" :
130+ return [
131+ {
132+ title : "Code" ,
133+ code : await htmlMain (
134+ convertedSelection ,
135+ { ...userPluginSettings , jsx : false } ,
136+ true ,
137+ ) ,
138+ language : "HTML" ,
139+ } ,
140+ {
141+ title : "Text Styles" ,
142+ code : htmlCodeGenTextStyles ( userPluginSettings ) ,
143+ language : "HTML" ,
144+ } ,
145+ ] ;
146+ case "html_jsx" :
147+ return [
148+ {
149+ title : "Code" ,
150+ code : await htmlMain (
151+ convertedSelection ,
152+ { ...userPluginSettings , jsx : true } ,
153+ true ,
154+ ) ,
155+ language : "HTML" ,
156+ } ,
157+ {
158+ title : "Text Styles" ,
159+ code : htmlCodeGenTextStyles ( userPluginSettings ) ,
160+ language : "HTML" ,
161+ } ,
162+ ] ;
163+ case "tailwind" :
164+ case "tailwind_jsx" :
165+ return [
166+ {
167+ title : "Code" ,
168+ code : await tailwindMain ( convertedSelection , {
169+ ...userPluginSettings ,
170+ jsx : language === "tailwind_jsx" ,
171+ } ) ,
172+ language : "HTML" ,
173+ } ,
174+ // {
175+ // title: "Style",
176+ // code: tailwindMain(convertedSelection, defaultPluginSettings),
177+ // language: "HTML",
178+ // },
179+ {
180+ title : "Tailwind Colors" ,
181+ code : retrieveGenericSolidUIColors ( "Tailwind" )
182+ . map ( ( d ) => {
183+ let str = `${ d . hex } ;` ;
184+ if ( d . colorName !== d . hex ) {
185+ str += ` // ${ d . colorName } ` ;
186+ }
187+ if ( d . meta ) {
188+ str += ` (${ d . meta } )` ;
189+ }
190+ return str ;
191+ } )
192+ . join ( "\n" ) ,
193+ language : "JAVASCRIPT" ,
194+ } ,
195+ {
196+ title : "Text Styles" ,
197+ code : tailwindCodeGenTextStyles ( ) ,
198+ language : "HTML" ,
199+ } ,
200+ ] ;
201+ case "flutter" :
202+ return [
203+ {
204+ title : "Code" ,
205+ code : flutterMain ( convertedSelection , {
206+ ...userPluginSettings ,
207+ flutterGenerationMode : "snippet" ,
208+ } ) ,
209+ language : "SWIFT" ,
210+ } ,
211+ {
212+ title : "Text Styles" ,
213+ code : flutterCodeGenTextStyles ( ) ,
214+ language : "SWIFT" ,
215+ } ,
216+ ] ;
217+ case "swiftUI" :
218+ return [
219+ {
220+ title : "SwiftUI" ,
221+ code : swiftuiMain ( convertedSelection , {
222+ ...userPluginSettings ,
223+ swiftUIGenerationMode : "snippet" ,
224+ } ) ,
225+ language : "SWIFT" ,
226+ } ,
227+ {
228+ title : "Text Styles" ,
229+ code : swiftUICodeGenTextStyles ( ) ,
230+ language : "SWIFT" ,
231+ } ,
232+ ] ;
233+ default :
234+ break ;
235+ }
219236
220- const blocks : CodegenResult [ ] = [ ] ;
221- return blocks ;
222- } ) ;
237+ const blocks : CodegenResult [ ] = [ ] ;
238+ return blocks ;
239+ } ,
240+ ) ;
223241} ;
224242
225243switch ( figma . mode ) {
0 commit comments