@@ -97,7 +97,7 @@ async function migrateTheme(
97
97
designSystem : DesignSystem ,
98
98
unresolvedConfig : Config ,
99
99
base : string ,
100
- ) : Promise < string | null > {
100
+ ) : Promise < string > {
101
101
// Resolve the config file without applying plugins and presets, as these are
102
102
// migrated to CSS separately.
103
103
let configToResolve : ConfigFile = {
@@ -114,10 +114,34 @@ async function migrateTheme(
114
114
115
115
removeUnnecessarySpacingKeys ( designSystem , resolvedConfig , replacedThemeKeys )
116
116
117
+ let css = ''
117
118
let prevSectionKey = ''
118
- let css = '\n@tw-bucket theme {\n'
119
- css += `\n@theme {\n`
120
- let containsThemeKeys = false
119
+ let themeSection : string [ ] = [ ]
120
+ let keyframesCss = ''
121
+
122
+ // Special handling of specific theme keys:
123
+ {
124
+ if ( 'keyframes' in resolvedConfig . theme ) {
125
+ keyframesCss += keyframesToCss ( resolvedConfig . theme . keyframes )
126
+ delete resolvedConfig . theme . keyframes
127
+ }
128
+
129
+ if ( 'container' in resolvedConfig . theme ) {
130
+ let rules = buildCustomContainerUtilityRules ( resolvedConfig . theme . container , designSystem )
131
+ if ( rules . length > 0 ) {
132
+ // Using `theme` instead of `utility` so it sits before the `@layer
133
+ // base` with compatibility CSS. While this is technically a utility, it
134
+ // makes a bit more sense to emit this closer to the `@theme` values
135
+ // since it is needed for backwards compatibility.
136
+ css += `\n@tw-bucket theme {\n`
137
+ css += toCss ( [ atRule ( '@utility' , 'container' , rules ) ] )
138
+ css += '}\n' // @tw -bucket
139
+ }
140
+ delete resolvedConfig . theme . container
141
+ }
142
+ }
143
+
144
+ // Convert theme values to CSS custom properties
121
145
for ( let [ key , value ] of themeableValues ( resolvedConfig . theme ) ) {
122
146
if ( typeof value !== 'string' && typeof value !== 'number' ) {
123
147
continue
@@ -152,51 +176,38 @@ async function migrateTheme(
152
176
}
153
177
}
154
178
155
- if ( key [ 0 ] === 'keyframes' ) {
156
- continue
157
- }
158
- containsThemeKeys = true
159
-
160
179
let sectionKey = createSectionKey ( key )
161
180
if ( sectionKey !== prevSectionKey ) {
162
- css += `\n`
181
+ themeSection . push ( '' )
163
182
prevSectionKey = sectionKey
164
183
}
165
184
166
185
if ( resetNamespaces . has ( key [ 0 ] ) && resetNamespaces . get ( key [ 0 ] ) === false ) {
167
186
resetNamespaces . set ( key [ 0 ] , true )
168
187
let property = keyPathToCssProperty ( [ key [ 0 ] ] )
169
188
if ( property !== null ) {
170
- css += ` ${ escape ( `--${ property } ` ) } -*: initial;\n`
189
+ themeSection . push ( ` ${ escape ( `--${ property } ` ) } -*: initial;` )
171
190
}
172
191
}
173
192
174
193
let property = keyPathToCssProperty ( key )
175
194
if ( property !== null ) {
176
- css += ` ${ escape ( `--${ property } ` ) } : ${ value } ;\n`
195
+ themeSection . push ( ` ${ escape ( `--${ property } ` ) } : ${ value } ;` )
177
196
}
178
197
}
179
198
180
- if ( 'keyframes' in resolvedConfig . theme ) {
181
- containsThemeKeys = true
182
- css += '\n' + keyframesToCss ( resolvedConfig . theme . keyframes )
199
+ if ( keyframesCss ) {
200
+ themeSection . push ( '' , keyframesCss )
183
201
}
184
202
185
- if ( ! containsThemeKeys ) {
186
- return null
203
+ if ( themeSection . length > 0 ) {
204
+ css += `\n@tw-bucket theme {\n`
205
+ css += `\n@theme {\n`
206
+ css += themeSection . join ( '\n' ) + '\n'
207
+ css += '}\n' // @theme
208
+ css += '}\n' // @tw -bucket
187
209
}
188
210
189
- css += '}\n' // @theme
190
-
191
- if ( 'container' in resolvedConfig . theme ) {
192
- let rules = buildCustomContainerUtilityRules ( resolvedConfig . theme . container , designSystem )
193
- if ( rules . length > 0 ) {
194
- css += '\n' + toCss ( [ atRule ( '@utility' , 'container' , rules ) ] )
195
- }
196
- }
197
-
198
- css += '}\n' // @tw -bucket
199
-
200
211
return css
201
212
}
202
213
0 commit comments