@@ -97,7 +97,7 @@ async function migrateTheme(
9797 designSystem : DesignSystem ,
9898 unresolvedConfig : Config ,
9999 base : string ,
100- ) : Promise < string | null > {
100+ ) : Promise < string > {
101101 // Resolve the config file without applying plugins and presets, as these are
102102 // migrated to CSS separately.
103103 let configToResolve : ConfigFile = {
@@ -114,10 +114,34 @@ async function migrateTheme(
114114
115115 removeUnnecessarySpacingKeys ( designSystem , resolvedConfig , replacedThemeKeys )
116116
117+ let css = ''
117118 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
121145 for ( let [ key , value ] of themeableValues ( resolvedConfig . theme ) ) {
122146 if ( typeof value !== 'string' && typeof value !== 'number' ) {
123147 continue
@@ -152,51 +176,38 @@ async function migrateTheme(
152176 }
153177 }
154178
155- if ( key [ 0 ] === 'keyframes' ) {
156- continue
157- }
158- containsThemeKeys = true
159-
160179 let sectionKey = createSectionKey ( key )
161180 if ( sectionKey !== prevSectionKey ) {
162- css += `\n`
181+ themeSection . push ( '' )
163182 prevSectionKey = sectionKey
164183 }
165184
166185 if ( resetNamespaces . has ( key [ 0 ] ) && resetNamespaces . get ( key [ 0 ] ) === false ) {
167186 resetNamespaces . set ( key [ 0 ] , true )
168187 let property = keyPathToCssProperty ( [ key [ 0 ] ] )
169188 if ( property !== null ) {
170- css += ` ${ escape ( `--${ property } ` ) } -*: initial;\n`
189+ themeSection . push ( ` ${ escape ( `--${ property } ` ) } -*: initial;` )
171190 }
172191 }
173192
174193 let property = keyPathToCssProperty ( key )
175194 if ( property !== null ) {
176- css += ` ${ escape ( `--${ property } ` ) } : ${ value } ;\n`
195+ themeSection . push ( ` ${ escape ( `--${ property } ` ) } : ${ value } ;` )
177196 }
178197 }
179198
180- if ( 'keyframes' in resolvedConfig . theme ) {
181- containsThemeKeys = true
182- css += '\n' + keyframesToCss ( resolvedConfig . theme . keyframes )
199+ if ( keyframesCss ) {
200+ themeSection . push ( '' , keyframesCss )
183201 }
184202
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
187209 }
188210
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-
200211 return css
201212}
202213
0 commit comments