@@ -172,6 +172,11 @@ const tailwindFrame = async (
172172 node : FrameNode | InstanceNode | ComponentNode | ComponentSetNode ,
173173 settings : TailwindSettings ,
174174) : Promise < string > => {
175+ // Check if this is an instance and should be rendered as a Twig component
176+ if ( node . type === "INSTANCE" && isTwigComponentNode ( node ) ) {
177+ return tailwindTwigComponentInstance ( node , settings ) ;
178+ }
179+
175180 const childrenStr = await tailwindWidgetGenerator ( node . children , settings ) ;
176181
177182 const clipsContentClass =
@@ -192,6 +197,57 @@ const tailwindFrame = async (
192197 return tailwindContainer ( node , childrenStr , combinedProps , settings ) ;
193198} ;
194199
200+
201+ // Helper function to generate Twig component syntax for component instances
202+ const tailwindTwigComponentInstance = async (
203+ node : InstanceNode ,
204+ settings : TailwindSettings ,
205+ ) : Promise < string > => {
206+ // Extract component name from the instance
207+ const componentName = extractComponentName ( node ) ;
208+
209+ // Get component properties if needed
210+ const builder = new TailwindDefaultBuilder ( node , settings )
211+ // .commonPositionStyles()
212+ // .commonShapeStyles()
213+ ;
214+
215+ const attributes = builder . build ( ) ;
216+
217+ // If we have children, process them
218+ let childrenStr = "" ;
219+
220+ const embeddableChildren = node . children ? node . children . filter ( ( n ) => isTwigContentNode ( n ) ) : [ ] ;
221+
222+ if ( embeddableChildren . length > 0 ) {
223+ // We keep embedded components and Frame named "TwigContent"
224+ childrenStr = await tailwindWidgetGenerator ( embeddableChildren , settings ) ;
225+ return `\n<twig:${ componentName } ${ attributes } >${ indentString ( childrenStr ) } \n</twig:${ componentName } >` ;
226+ } else {
227+ // Self-closing tag if no children
228+ return `\n<twig:${ componentName } ${ attributes } />` ;
229+ }
230+ } ;
231+
232+ const isTwigComponentNode = ( node : SceneNode ) : boolean => {
233+ return localTailwindSettings . tailwindGenerationMode === "twig" && node . type === "INSTANCE" && ! extractComponentName ( node ) . startsWith ( "HTML:" ) && ! isTwigContentNode ( node ) ;
234+ }
235+
236+ const isTwigContentNode = ( node : SceneNode ) : boolean => {
237+ return node . type === "INSTANCE" && node . name . startsWith ( "TwigContent" ) ;
238+ }
239+
240+ // Helper function to extract component name from an instance
241+ const extractComponentName = ( node : InstanceNode ) : string => {
242+ // Try to get name from mainComponent if available
243+ if ( node . mainComponent ) {
244+ return node . mainComponent . name ;
245+ }
246+
247+ // Fallback to node name if mainComponent is not available
248+ return node . name ;
249+ } ;
250+
195251export const tailwindContainer = (
196252 node : SceneNode &
197253 SceneNodeMixin &
0 commit comments