@@ -82,8 +82,13 @@ export async function exportDevup(
8282 // Build both ID-keyed and name-keyed maps from a single fetch
8383 const stylesById = new Map < string , TextStyle > ( )
8484 const styles : Record < string , TextStyle > = { }
85+ const styleMetaById = new Map < string , { level : number ; name : string } > ( )
86+ const allTypographyKeys = new Set < string > ( )
8587 for ( const style of textStyles ) {
88+ const meta = styleNameToTypography ( style . name )
8689 stylesById . set ( style . id , style )
90+ styleMetaById . set ( style . id , meta )
91+ allTypographyKeys . add ( meta . name )
8792 styles [ style . name ] = style
8893 }
8994
@@ -94,47 +99,76 @@ export async function exportDevup(
9499 const prevSkip = figma . skipInvisibleInstanceChildren
95100 figma . skipInvisibleInstanceChildren = true
96101
97- const tFind = perfStart ( )
98- const texts = figma . root . findAllWithCriteria ( { types : [ 'TEXT' ] } )
99- perfEnd ( 'exportDevup.typography.find' , tFind )
100-
101- const tScan = perfStart ( )
102- const foundStyleIds = new Set < string > ( )
103- for ( const text of texts ) {
104- // Early exit: all local styles discovered
105- if ( foundStyleIds . size >= stylesById . size ) break
102+ const usedTypographyKeys = new Set < string > ( )
103+ const processText = ( text : TextNode ) => {
104+ if ( usedTypographyKeys . size >= allTypographyKeys . size ) return
106105 if (
107106 ! ( typeof text . textStyleId === 'string' && text . textStyleId ) &&
108107 text . textStyleId !== figma . mixed
109108 )
110- continue
109+ return
111110
112111 if ( typeof text . textStyleId === 'string' ) {
113- // Single-style node — skip getStyledTextSegments entirely
114112 const style = stylesById . get ( text . textStyleId )
115- if ( ! style || foundStyleIds . has ( text . textStyleId ) ) continue
116- foundStyleIds . add ( text . textStyleId )
117- const { level, name } = styleNameToTypography ( style . name )
113+ const meta = styleMetaById . get ( text . textStyleId )
114+ if ( ! style || ! meta || usedTypographyKeys . has ( meta . name ) ) return
115+ usedTypographyKeys . add ( meta . name )
116+ const { level, name } = meta
118117 if ( ! typography [ name ] ?. [ level ] ) {
119118 typography [ name ] ??= [ null , null , null , null , null , null ]
120119 typography [ name ] [ level ] = textStyleToTypography ( style )
121120 }
122- continue
121+ return
123122 }
124123
125- // Mixed-style node — only request textStyleId (1 field vs 8)
126124 for ( const seg of text . getStyledTextSegments ( [ 'textStyleId' ] ) ) {
127- if ( ! seg ?. textStyleId || foundStyleIds . has ( seg . textStyleId ) ) continue
125+ if ( usedTypographyKeys . size >= allTypographyKeys . size ) return
126+ if ( ! seg ?. textStyleId ) continue
128127 const style = stylesById . get ( seg . textStyleId )
129- if ( ! style ) continue
130- foundStyleIds . add ( seg . textStyleId )
131- const { level, name } = styleNameToTypography ( style . name )
128+ const meta = styleMetaById . get ( seg . textStyleId )
129+ if ( ! style || ! meta || usedTypographyKeys . has ( meta . name ) ) continue
130+ usedTypographyKeys . add ( meta . name )
131+ const { level, name } = meta
132132 if ( typography [ name ] ?. [ level ] ) continue
133133 typography [ name ] ??= [ null , null , null , null , null , null ]
134134 typography [ name ] [ level ] = textStyleToTypography ( style )
135135 }
136136 }
137- perfEnd ( 'exportDevup.typography.scan' , tScan )
137+
138+ const rootPages = Array . isArray ( figma . root . children )
139+ ? figma . root . children
140+ : [ ]
141+ if ( rootPages . length > 1 ) {
142+ const currentPageId = figma . currentPage . id
143+ const orderedPages = [
144+ figma . currentPage ,
145+ ...rootPages . filter ( ( page ) => page . id !== currentPageId ) ,
146+ ]
147+ for ( const page of orderedPages ) {
148+ if ( usedTypographyKeys . size >= allTypographyKeys . size ) break
149+ const tFind = perfStart ( )
150+ const texts = page . findAllWithCriteria ( { types : [ 'TEXT' ] } )
151+ perfEnd ( 'exportDevup.typography.find' , tFind )
152+
153+ const tScan = perfStart ( )
154+ for ( const text of texts ) {
155+ processText ( text )
156+ if ( usedTypographyKeys . size >= allTypographyKeys . size ) break
157+ }
158+ perfEnd ( 'exportDevup.typography.scan' , tScan )
159+ }
160+ } else {
161+ const tFind = perfStart ( )
162+ const texts = figma . root . findAllWithCriteria ( { types : [ 'TEXT' ] } )
163+ perfEnd ( 'exportDevup.typography.find' , tFind )
164+
165+ const tScan = perfStart ( )
166+ for ( const text of texts ) {
167+ processText ( text )
168+ if ( usedTypographyKeys . size >= allTypographyKeys . size ) break
169+ }
170+ perfEnd ( 'exportDevup.typography.scan' , tScan )
171+ }
138172
139173 figma . skipInvisibleInstanceChildren = prevSkip
140174 } else {
0 commit comments