11import { rule } from '../ast'
22import type { DesignSystem } from '../design-system'
33import type { ResolvedConfig } from './config/types'
4- import DefaultTheme from './default-theme'
54
6- export function registerScreensConfig ( config : ResolvedConfig , designSystem : DesignSystem ) {
7- let screens = config . theme . screens || { }
5+ export function registerScreensConfig ( userConfig : ResolvedConfig , designSystem : DesignSystem ) {
6+ let screens = userConfig . theme . screens || { }
87
98 // We want to insert the breakpoints in the right order as best we can. In the
109 // core utility, all static breakpoint variants and the `min-*` functional
@@ -18,16 +17,6 @@ export function registerScreensConfig(config: ResolvedConfig, designSystem: Desi
1817 for ( let [ name , value ] of Object . entries ( screens ) ) {
1918 let coreVariant = designSystem . variants . get ( name )
2019
21- // Ignore defaults if they are already registered
22- //
23- // Note: We can't rely on the `designSystem.theme` for this, as it has the
24- // JS config values applied already. However, the DefaultTheme might not
25- // match what is actually already set in the designSystem since the @theme
26- // is set at runtime.
27- if ( coreVariant && DefaultTheme . screens [ name as 'sm' ] === screens [ name ] ) {
28- continue
29- }
30-
3120 // Ignore it if there's a CSS value that takes precedence over the JS config
3221 // and the static utilities are already registered.
3322 //
@@ -36,19 +25,75 @@ export function registerScreensConfig(config: ResolvedConfig, designSystem: Desi
3625 // resolving this. If Theme has a different value, we know that this is not
3726 // coming from the JS plugin and thus we don't need to handle it explicitly.
3827 let cssValue = designSystem . theme . resolveValue ( name , [ '--breakpoint' ] )
39- if ( coreVariant && cssValue && cssValue !== value ) {
28+ if ( coreVariant && cssValue && ! designSystem . theme . hasDefault ( `--breakpoint- ${ name } ` ) ) {
4029 continue
4130 }
4231
4332 // min-${breakpoint} and max-${breakpoint} rules do not need to be
4433 // reconfigured, as they are using functional utilities and will not eagerly
4534 // capture the breakpoints before the compat layer runs.
35+ let query : string | undefined
36+ let insertOrder : number | undefined
37+ if ( typeof value === 'string' ) {
38+ query = `(width >= ${ value } )`
39+ insertOrder = order
40+ } else if ( typeof value === 'object' && value !== null ) {
41+ if ( Array . isArray ( value ) ) {
42+ query = value . map ( ruleForComplexScreenValue ) . join ( ', ' )
43+ } else {
44+ query = ruleForComplexScreenValue ( value ) ?? ''
45+ if ( 'min' in value && ! ( 'max' in value ) ) {
46+ insertOrder = order
47+ }
48+ }
49+ } else {
50+ continue
51+ }
52+
53+ if ( order && insertOrder === undefined ) {
54+ insertOrder = allocateOrderAfter ( designSystem , order )
55+ }
56+
4657 designSystem . variants . static (
4758 name ,
4859 ( ruleNode ) => {
49- ruleNode . nodes = [ rule ( `@media (width >= ${ value } ) ` , ruleNode . nodes ) ]
60+ ruleNode . nodes = [ rule ( `@media ${ query } ` , ruleNode . nodes ) ]
5061 } ,
51- { order } ,
62+ { order : insertOrder } ,
5263 )
5364 }
5465}
66+
67+ function allocateOrderAfter ( designSystem : DesignSystem , order : number ) : number {
68+ for ( let [ , variant ] of designSystem . variants . variants ) {
69+ if ( variant . order > order ) variant . order ++
70+ }
71+ designSystem . variants . compareFns = new Map (
72+ Array . from ( designSystem . variants . compareFns ) . map ( ( [ key , value ] ) => {
73+ if ( key > order ) key ++
74+ return [ key , value ]
75+ } ) ,
76+ )
77+ return order + 1
78+ }
79+
80+ function ruleForComplexScreenValue ( value : object ) : string | null {
81+ let query = null
82+ if ( 'raw' in value && typeof value . raw === 'string' ) {
83+ query = value . raw
84+ } else {
85+ let rules : string [ ] = [ ]
86+
87+ if ( 'min' in value && typeof value . min === 'string' ) {
88+ rules . push ( `min-width: ${ value . min } ` )
89+ }
90+ if ( 'max' in value && typeof value . max === 'string' ) {
91+ rules . push ( `max-width: ${ value . max } ` )
92+ }
93+
94+ if ( rules . length !== 0 ) {
95+ query = `(${ rules . join ( ' and ' ) } )`
96+ }
97+ }
98+ return query
99+ }
0 commit comments