@@ -102,8 +102,8 @@ const cloneRuleWithParent = useMemo(
102102 ( rule ) => rule
103103)
104104
105- function buildUtilityMap ( css , lookupTree ) {
106- let index = 0
105+ function buildCssUtilityMap ( css , startIndex ) {
106+ let index = startIndex
107107 const utilityMap = { }
108108
109109 function handle ( getRule , rule ) {
@@ -124,16 +124,6 @@ function buildUtilityMap(css, lookupTree) {
124124 } )
125125 }
126126
127- // Lookup tree is the big lookup tree, making the rule lazy allows us to save
128- // some memory because we don't need everything.
129- lookupTree . walkRules (
130- handle . bind ( null , ( rule ) => ( {
131- get rule ( ) {
132- return cloneRuleWithParent ( rule )
133- } ,
134- } ) )
135- )
136-
137127 // This is the end user's css. This might contain rules that we want to
138128 // apply. We want immediate copies of everything in case that we have user
139129 // defined classes that are recursively applied. Down below we are modifying
@@ -145,6 +135,44 @@ function buildUtilityMap(css, lookupTree) {
145135 return utilityMap
146136}
147137
138+ const buildLookupTreeUtilityMap = useMemo (
139+ ( lookupTree ) => {
140+ let index = 0
141+ const utilityMap = { }
142+
143+ function handle ( getRule , rule ) {
144+ const utilityNames = extractUtilityNames ( rule . selector )
145+
146+ utilityNames . forEach ( ( utilityName , i ) => {
147+ if ( utilityMap [ utilityName ] === undefined ) {
148+ utilityMap [ utilityName ] = [ ]
149+ }
150+
151+ utilityMap [ utilityName ] . push ( {
152+ index,
153+ utilityName,
154+ classPosition : i ,
155+ ...getRule ( rule ) ,
156+ } )
157+ index ++
158+ } )
159+ }
160+
161+ // Lookup tree is the big lookup tree, making the rule lazy allows us to save
162+ // some memory because we don't need everything.
163+ lookupTree . walkRules (
164+ handle . bind ( null , ( rule ) => ( {
165+ get rule ( ) {
166+ return cloneRuleWithParent ( rule )
167+ } ,
168+ } ) )
169+ )
170+
171+ return utilityMap
172+ } ,
173+ ( tree ) => tree
174+ )
175+
148176function mergeAdjacentRules ( initialRule , rulesToInsert ) {
149177 let previousRule = initialRule
150178
@@ -181,23 +209,41 @@ function mergeAdjacentRules(initialRule, rulesToInsert) {
181209}
182210
183211function makeExtractUtilityRules ( css , lookupTree , config ) {
184- const utilityMap = buildUtilityMap ( css , lookupTree )
212+ const lookupTreeUtilityMap = buildLookupTreeUtilityMap ( lookupTree )
213+ const lookupTreeUtilityMapKeys = Object . keys ( lookupTreeUtilityMap )
214+ const utilityMap = buildCssUtilityMap ( css , lookupTreeUtilityMapKeys . length )
215+
216+ function getUtility ( utilityName ) {
217+ const utility = [ ]
218+ if ( lookupTreeUtilityMap [ utilityName ] ) {
219+ utility . push ( ...lookupTreeUtilityMap [ utilityName ] )
220+ }
221+ if ( utilityMap [ utilityName ] ) {
222+ utility . push ( ...utilityMap [ utilityName ] )
223+ }
224+ if ( utility . length > 0 ) return utility
225+ }
185226
186227 return function extractUtilityRules ( utilityNames , rule ) {
187228 const combined = [ ]
188229
189230 utilityNames . forEach ( ( utilityName ) => {
190- if ( utilityMap [ utilityName ] === undefined ) {
231+ const utility = getUtility ( utilityName )
232+ if ( utility === undefined ) {
191233 // Look for prefixed utility in case the user has goofed
192- const prefixedUtility = prefixSelector ( config . prefix , `.${ utilityName } ` ) . slice ( 1 )
234+ const prefixedUtilityName = prefixSelector ( config . prefix , `.${ utilityName } ` ) . slice ( 1 )
193235
194- if ( utilityMap [ prefixedUtility ] !== undefined ) {
236+ const prefixedUtility = getUtility ( prefixedUtilityName )
237+ if ( prefixedUtility !== undefined ) {
195238 throw rule . error (
196- `The \`${ utilityName } \` class does not exist, but \`${ prefixedUtility } \` does. Did you forget the prefix?`
239+ `The \`${ utilityName } \` class does not exist, but \`${ prefixedUtilityName } \` does. Did you forget the prefix?`
197240 )
198241 }
199242
200- const suggestedClass = didYouMean ( utilityName , Object . keys ( utilityMap ) )
243+ const suggestedClass = didYouMean (
244+ utilityName ,
245+ Object . keys ( utilityMap ) . concat ( lookupTreeUtilityMapKeys )
246+ )
201247 const suggestionMessage = suggestedClass ? `, but \`${ suggestedClass } \` does` : ''
202248
203249 throw rule . error (
@@ -206,7 +252,7 @@ function makeExtractUtilityRules(css, lookupTree, config) {
206252 )
207253 }
208254
209- combined . push ( ...utilityMap [ utilityName ] )
255+ combined . push ( ...utility )
210256 } )
211257
212258 return combined . sort ( ( a , b ) => a . index - b . index )
0 commit comments