Skip to content

Commit 4e129be

Browse files
Refactor some screen compatibility code (#14465)
These changes were extracted from our work on a `screen()` function for CSS — we've decided to move those changes to a code mod instead of implementing support for `screen()` in the compiler — but the refactoring around the changes still makes sense to do so I'm landing that here separately. --------- Co-authored-by: Philipp Spiess <[email protected]>
1 parent ba5b9af commit 4e129be

File tree

4 files changed

+76
-35
lines changed

4 files changed

+76
-35
lines changed

packages/tailwindcss/src/compat/config/resolve-config.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -203,4 +203,19 @@ function mergeTheme(ctx: ResolutionContext) {
203203
for (let key in ctx.theme) {
204204
ctx.theme[key] = resolveValue(ctx.theme[key])
205205
}
206+
207+
// Turn {min: '123px'} into '123px' in screens
208+
if (ctx.theme.screens && typeof ctx.theme.screens === 'object') {
209+
for (let key of Object.keys(ctx.theme.screens)) {
210+
let screen = ctx.theme.screens[key]
211+
if (!screen) continue
212+
if (typeof screen !== 'object') continue
213+
214+
if ('raw' in screen) continue
215+
if ('max' in screen) continue
216+
if (!('min' in screen)) continue
217+
218+
ctx.theme.screens[key] = screen.min
219+
}
220+
}
206221
}

packages/tailwindcss/src/compat/screens-config.test.ts

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -457,7 +457,7 @@ describe('complex screen configs', () => {
457457
md: [
458458
//
459459
{ min: '668px', max: '767px' },
460-
{ min: '868px' },
460+
'868px',
461461
],
462462
lg: { min: '868px' },
463463
xl: { min: '1024px', max: '1279px' },
@@ -468,15 +468,14 @@ describe('complex screen configs', () => {
468468
}),
469469
})
470470

471-
expect(
472-
compiler.build(['min-sm:flex', 'min-md:flex', 'min-lg:flex', 'min-xl:flex', 'min-tall:flex']),
473-
).toBe('')
471+
expect(compiler.build(['min-sm:flex', 'min-md:flex', 'min-xl:flex', 'min-tall:flex'])).toBe('')
474472

475473
expect(
476474
compiler.build([
477475
'sm:flex',
478476
'md:flex',
479477
'lg:flex',
478+
'min-lg:flex',
480479
'xl:flex',
481480
'tall:flex',
482481

@@ -485,22 +484,27 @@ describe('complex screen configs', () => {
485484
]),
486485
).toMatchInlineSnapshot(`
487486
".lg\\:flex {
488-
@media (min-width: 868px) {
487+
@media (width >= 868px) {
488+
display: flex;
489+
}
490+
}
491+
.min-lg\\:flex {
492+
@media (width >= 868px) {
489493
display: flex;
490494
}
491495
}
492496
.sm\\:flex {
493-
@media (max-width: 639px) {
497+
@media (639px >= width) {
494498
display: flex;
495499
}
496500
}
497501
.md\\:flex {
498-
@media (min-width: 668px and max-width: 767px), (min-width: 868px) {
502+
@media (767px >= width >= 668px), (width >= 868px) {
499503
display: flex;
500504
}
501505
}
502506
.xl\\:flex {
503-
@media (min-width: 1024px and max-width: 1279px) {
507+
@media (1279px >= width >= 1024px) {
504508
display: flex;
505509
}
506510
}

packages/tailwindcss/src/compat/screens-config.ts

Lines changed: 44 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -31,24 +31,14 @@ export function registerScreensConfig(userConfig: ResolvedConfig, designSystem:
3131
continue
3232
}
3333

34-
let query: string | undefined
3534
let deferInsert = true
35+
3636
if (typeof value === 'string') {
37-
query = `(width >= ${value})`
3837
deferInsert = false
39-
} else if (typeof value === 'object' && value !== null) {
40-
if (Array.isArray(value)) {
41-
query = value.map(ruleForComplexScreenValue).join(', ')
42-
} else {
43-
query = ruleForComplexScreenValue(value) ?? ''
44-
if ('min' in value && !('max' in value)) {
45-
deferInsert = false
46-
}
47-
}
48-
} else {
49-
continue
5038
}
5139

40+
let query = buildMediaQuery(value)
41+
5242
function insert(order: number) {
5343
// `min-*` and `max-*` rules do not need to be reconfigured, as they are
5444
// reading the latest values from the theme.
@@ -87,19 +77,47 @@ export function registerScreensConfig(userConfig: ResolvedConfig, designSystem:
8777
}
8878
}
8979

90-
function ruleForComplexScreenValue(value: object): string | null {
91-
let query = null
92-
if ('raw' in value && typeof value.raw === 'string') {
93-
query = value.raw
94-
} else {
95-
let rules: string[] = []
80+
export function buildMediaQuery(values: unknown) {
81+
type ScreenDescriptor = {
82+
min?: string
83+
max?: string
84+
raw?: string
85+
}
9686

97-
if ('min' in value) rules.push(`min-width: ${value.min}`)
98-
if ('max' in value) rules.push(`max-width: ${value.max}`)
87+
let list: unknown[] = Array.isArray(values) ? values : [values]
88+
return list
89+
.map((value): ScreenDescriptor | null => {
90+
if (typeof value === 'string') {
91+
return { min: value }
92+
}
9993

100-
if (rules.length !== 0) {
101-
query = `(${rules.join(' and ')})`
102-
}
103-
}
104-
return query
94+
if (value && typeof value === 'object') {
95+
return value
96+
}
97+
98+
return null
99+
})
100+
.map((screen) => {
101+
if (screen === null) return null
102+
103+
if ('raw' in screen) {
104+
return screen.raw
105+
}
106+
107+
let query = ''
108+
109+
if (screen.max !== undefined) {
110+
query += `${screen.max} >= `
111+
}
112+
113+
query += 'width'
114+
115+
if (screen.min !== undefined) {
116+
query += ` >= ${screen.min}`
117+
}
118+
119+
return `(${query})`
120+
})
121+
.filter(Boolean)
122+
.join(', ')
105123
}

packages/tailwindcss/src/css-functions.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,13 @@ export function substituteFunctions(ast: AstNode[], resolveThemeValue: ResolveTh
1919
if (
2020
node.selector[0] === '@' &&
2121
(node.selector.startsWith('@media ') ||
22+
node.selector.startsWith('@media(') ||
2223
node.selector.startsWith('@custom-media ') ||
24+
node.selector.startsWith('@custom-media(') ||
2325
node.selector.startsWith('@container ') ||
24-
node.selector.startsWith('@supports ')) &&
26+
node.selector.startsWith('@container(') ||
27+
node.selector.startsWith('@supports ') ||
28+
node.selector.startsWith('@supports(')) &&
2529
node.selector.includes(THEME_FUNCTION_INVOCATION)
2630
) {
2731
node.selector = substituteFunctionsInValue(node.selector, resolveThemeValue)

0 commit comments

Comments
 (0)