@@ -102,8 +102,8 @@ const cloneRuleWithParent = useMemo(
102
102
( rule ) => rule
103
103
)
104
104
105
- function buildUtilityMap ( css , lookupTree ) {
106
- let index = 0
105
+ function buildCssUtilityMap ( css , startIndex ) {
106
+ let index = startIndex
107
107
const utilityMap = { }
108
108
109
109
function handle ( getRule , rule ) {
@@ -124,16 +124,6 @@ function buildUtilityMap(css, lookupTree) {
124
124
} )
125
125
}
126
126
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
-
137
127
// This is the end user's css. This might contain rules that we want to
138
128
// apply. We want immediate copies of everything in case that we have user
139
129
// defined classes that are recursively applied. Down below we are modifying
@@ -145,6 +135,44 @@ function buildUtilityMap(css, lookupTree) {
145
135
return utilityMap
146
136
}
147
137
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
+
148
176
function mergeAdjacentRules ( initialRule , rulesToInsert ) {
149
177
let previousRule = initialRule
150
178
@@ -181,23 +209,41 @@ function mergeAdjacentRules(initialRule, rulesToInsert) {
181
209
}
182
210
183
211
function 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
+ }
185
226
186
227
return function extractUtilityRules ( utilityNames , rule ) {
187
228
const combined = [ ]
188
229
189
230
utilityNames . forEach ( ( utilityName ) => {
190
- if ( utilityMap [ utilityName ] === undefined ) {
231
+ const utility = getUtility ( utilityName )
232
+ if ( utility === undefined ) {
191
233
// 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 )
193
235
194
- if ( utilityMap [ prefixedUtility ] !== undefined ) {
236
+ const prefixedUtility = getUtility ( prefixedUtilityName )
237
+ if ( prefixedUtility !== undefined ) {
195
238
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?`
197
240
)
198
241
}
199
242
200
- const suggestedClass = didYouMean ( utilityName , Object . keys ( utilityMap ) )
243
+ const suggestedClass = didYouMean (
244
+ utilityName ,
245
+ Object . keys ( utilityMap ) . concat ( lookupTreeUtilityMapKeys )
246
+ )
201
247
const suggestionMessage = suggestedClass ? `, but \`${ suggestedClass } \` does` : ''
202
248
203
249
throw rule . error (
@@ -206,7 +252,7 @@ function makeExtractUtilityRules(css, lookupTree, config) {
206
252
)
207
253
}
208
254
209
- combined . push ( ...utilityMap [ utilityName ] )
255
+ combined . push ( ...utility )
210
256
} )
211
257
212
258
return combined . sort ( ( a , b ) => a . index - b . index )
0 commit comments