Skip to content

Commit 5da2036

Browse files
authored
Merge pull request #645 from tailwindcss/theme-closures
Support using closures as theme values to enable self-referencing
2 parents a485400 + 0318bd2 commit 5da2036

File tree

5 files changed

+243
-105
lines changed

5 files changed

+243
-105
lines changed

__tests__/mergeConfigWithDefaults.test.js renamed to __tests__/resolveConfig.test.js

Lines changed: 137 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import mergeConfigWithDefaults from '../src/util/mergeConfigWithDefaults'
1+
import resolveConfig from '../src/util/resolveConfig'
22

33
test('prefix key overrides default prefix', () => {
44
const userConfig = {
@@ -21,7 +21,7 @@ test('prefix key overrides default prefix', () => {
2121
},
2222
}
2323

24-
const result = mergeConfigWithDefaults(userConfig, defaultConfig)
24+
const result = resolveConfig([userConfig, defaultConfig])
2525

2626
expect(result).toEqual({
2727
prefix: 'tw-',
@@ -61,7 +61,7 @@ test('important key overrides default important', () => {
6161
},
6262
}
6363

64-
const result = mergeConfigWithDefaults(userConfig, defaultConfig)
64+
const result = resolveConfig([userConfig, defaultConfig])
6565

6666
expect(result).toEqual({
6767
prefix: '',
@@ -101,7 +101,7 @@ test('separator key overrides default separator', () => {
101101
},
102102
}
103103

104-
const result = mergeConfigWithDefaults(userConfig, defaultConfig)
104+
const result = resolveConfig([userConfig, defaultConfig])
105105

106106
expect(result).toEqual({
107107
prefix: '',
@@ -158,7 +158,7 @@ test('theme key is merged instead of replaced', () => {
158158
},
159159
}
160160

161-
const result = mergeConfigWithDefaults(userConfig, defaultConfig)
161+
const result = resolveConfig([userConfig, defaultConfig])
162162

163163
expect(result).toEqual({
164164
prefix: '-',
@@ -227,7 +227,7 @@ test('variants key is merged instead of replaced', () => {
227227
},
228228
}
229229

230-
const result = mergeConfigWithDefaults(userConfig, defaultConfig)
230+
const result = resolveConfig([userConfig, defaultConfig])
231231

232232
expect(result).toEqual({
233233
prefix: '-',
@@ -281,7 +281,7 @@ test('missing top level keys are pulled from the default config', () => {
281281
},
282282
}
283283

284-
const result = mergeConfigWithDefaults(userConfig, defaultConfig)
284+
const result = resolveConfig([userConfig, defaultConfig])
285285

286286
expect(result).toEqual({
287287
prefix: '-',
@@ -300,3 +300,133 @@ test('missing top level keys are pulled from the default config', () => {
300300
},
301301
})
302302
})
303+
304+
test('functions in the default theme section are lazily evaluated', () => {
305+
const userConfig = {
306+
theme: {
307+
colors: {
308+
red: 'red',
309+
green: 'green',
310+
blue: 'blue',
311+
},
312+
},
313+
}
314+
315+
const defaultConfig = {
316+
prefix: '-',
317+
important: false,
318+
separator: ':',
319+
theme: {
320+
colors: {
321+
cyan: 'cyan',
322+
magenta: 'magenta',
323+
yellow: 'yellow',
324+
},
325+
backgroundColors: ({ colors }) => colors,
326+
textColors: ({ colors }) => colors,
327+
},
328+
variants: {
329+
backgroundColors: ['responsive', 'hover', 'focus'],
330+
textColors: ['responsive', 'hover', 'focus'],
331+
},
332+
}
333+
334+
const result = resolveConfig([userConfig, defaultConfig])
335+
336+
expect(result).toEqual({
337+
prefix: '-',
338+
important: false,
339+
separator: ':',
340+
theme: {
341+
colors: {
342+
red: 'red',
343+
green: 'green',
344+
blue: 'blue',
345+
},
346+
backgroundColors: {
347+
red: 'red',
348+
green: 'green',
349+
blue: 'blue',
350+
},
351+
textColors: {
352+
red: 'red',
353+
green: 'green',
354+
blue: 'blue',
355+
},
356+
},
357+
variants: {
358+
backgroundColors: ['responsive', 'hover', 'focus'],
359+
textColors: ['responsive', 'hover', 'focus'],
360+
},
361+
})
362+
})
363+
364+
test('functions in the user theme section are lazily evaluated', () => {
365+
const userConfig = {
366+
theme: {
367+
colors: {
368+
red: 'red',
369+
green: 'green',
370+
blue: 'blue',
371+
},
372+
backgroundColors: ({ colors }) => ({
373+
...colors,
374+
customBackground: '#bada55',
375+
}),
376+
textColors: ({ colors }) => ({
377+
...colors,
378+
customText: '#facade',
379+
}),
380+
},
381+
}
382+
383+
const defaultConfig = {
384+
prefix: '-',
385+
important: false,
386+
separator: ':',
387+
theme: {
388+
colors: {
389+
cyan: 'cyan',
390+
magenta: 'magenta',
391+
yellow: 'yellow',
392+
},
393+
backgroundColors: ({ colors }) => colors,
394+
textColors: ({ colors }) => colors,
395+
},
396+
variants: {
397+
backgroundColors: ['responsive', 'hover', 'focus'],
398+
textColors: ['responsive', 'hover', 'focus'],
399+
},
400+
}
401+
402+
const result = resolveConfig([userConfig, defaultConfig])
403+
404+
expect(result).toEqual({
405+
prefix: '-',
406+
important: false,
407+
separator: ':',
408+
theme: {
409+
colors: {
410+
red: 'red',
411+
green: 'green',
412+
blue: 'blue',
413+
},
414+
backgroundColors: {
415+
red: 'red',
416+
green: 'green',
417+
blue: 'blue',
418+
customBackground: '#bada55',
419+
},
420+
textColors: {
421+
red: 'red',
422+
green: 'green',
423+
blue: 'blue',
424+
customText: '#facade',
425+
},
426+
},
427+
variants: {
428+
backgroundColors: ['responsive', 'hover', 'focus'],
429+
textColors: ['responsive', 'hover', 'focus'],
430+
},
431+
})
432+
})

defaultTheme.js

Lines changed: 81 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -1,92 +1,90 @@
11
module.exports = function() {
2-
const colors = {
3-
transparent: 'transparent',
4-
5-
black: '#22292f',
6-
'grey-darkest': '#3d4852',
7-
'grey-darker': '#606f7b',
8-
'grey-dark': '#8795a1',
9-
grey: '#b8c2cc',
10-
'grey-light': '#dae1e7',
11-
'grey-lighter': '#f1f5f8',
12-
'grey-lightest': '#f8fafc',
13-
white: '#ffffff',
2+
return {
3+
colors: {
4+
transparent: 'transparent',
145

15-
'red-darkest': '#3b0d0c',
16-
'red-darker': '#621b18',
17-
'red-dark': '#cc1f1a',
18-
red: '#e3342f',
19-
'red-light': '#ef5753',
20-
'red-lighter': '#f9acaa',
21-
'red-lightest': '#fcebea',
6+
black: '#22292f',
7+
'grey-darkest': '#3d4852',
8+
'grey-darker': '#606f7b',
9+
'grey-dark': '#8795a1',
10+
grey: '#b8c2cc',
11+
'grey-light': '#dae1e7',
12+
'grey-lighter': '#f1f5f8',
13+
'grey-lightest': '#f8fafc',
14+
white: '#ffffff',
2215

23-
'orange-darkest': '#462a16',
24-
'orange-darker': '#613b1f',
25-
'orange-dark': '#de751f',
26-
orange: '#f6993f',
27-
'orange-light': '#faad63',
28-
'orange-lighter': '#fcd9b6',
29-
'orange-lightest': '#fff5eb',
16+
'red-darkest': '#3b0d0c',
17+
'red-darker': '#621b18',
18+
'red-dark': '#cc1f1a',
19+
red: '#e3342f',
20+
'red-light': '#ef5753',
21+
'red-lighter': '#f9acaa',
22+
'red-lightest': '#fcebea',
3023

31-
'yellow-darkest': '#453411',
32-
'yellow-darker': '#684f1d',
33-
'yellow-dark': '#f2d024',
34-
yellow: '#ffed4a',
35-
'yellow-light': '#fff382',
36-
'yellow-lighter': '#fff9c2',
37-
'yellow-lightest': '#fcfbeb',
24+
'orange-darkest': '#462a16',
25+
'orange-darker': '#613b1f',
26+
'orange-dark': '#de751f',
27+
orange: '#f6993f',
28+
'orange-light': '#faad63',
29+
'orange-lighter': '#fcd9b6',
30+
'orange-lightest': '#fff5eb',
3831

39-
'green-darkest': '#0f2f21',
40-
'green-darker': '#1a4731',
41-
'green-dark': '#1f9d55',
42-
green: '#38c172',
43-
'green-light': '#51d88a',
44-
'green-lighter': '#a2f5bf',
45-
'green-lightest': '#e3fcec',
32+
'yellow-darkest': '#453411',
33+
'yellow-darker': '#684f1d',
34+
'yellow-dark': '#f2d024',
35+
yellow: '#ffed4a',
36+
'yellow-light': '#fff382',
37+
'yellow-lighter': '#fff9c2',
38+
'yellow-lightest': '#fcfbeb',
4639

47-
'teal-darkest': '#0d3331',
48-
'teal-darker': '#20504f',
49-
'teal-dark': '#38a89d',
50-
teal: '#4dc0b5',
51-
'teal-light': '#64d5ca',
52-
'teal-lighter': '#a0f0ed',
53-
'teal-lightest': '#e8fffe',
40+
'green-darkest': '#0f2f21',
41+
'green-darker': '#1a4731',
42+
'green-dark': '#1f9d55',
43+
green: '#38c172',
44+
'green-light': '#51d88a',
45+
'green-lighter': '#a2f5bf',
46+
'green-lightest': '#e3fcec',
5447

55-
'blue-darkest': '#12283a',
56-
'blue-darker': '#1c3d5a',
57-
'blue-dark': '#2779bd',
58-
blue: '#3490dc',
59-
'blue-light': '#6cb2eb',
60-
'blue-lighter': '#bcdefa',
61-
'blue-lightest': '#eff8ff',
48+
'teal-darkest': '#0d3331',
49+
'teal-darker': '#20504f',
50+
'teal-dark': '#38a89d',
51+
teal: '#4dc0b5',
52+
'teal-light': '#64d5ca',
53+
'teal-lighter': '#a0f0ed',
54+
'teal-lightest': '#e8fffe',
6255

63-
'indigo-darkest': '#191e38',
64-
'indigo-darker': '#2f365f',
65-
'indigo-dark': '#5661b3',
66-
indigo: '#6574cd',
67-
'indigo-light': '#7886d7',
68-
'indigo-lighter': '#b2b7ff',
69-
'indigo-lightest': '#e6e8ff',
56+
'blue-darkest': '#12283a',
57+
'blue-darker': '#1c3d5a',
58+
'blue-dark': '#2779bd',
59+
blue: '#3490dc',
60+
'blue-light': '#6cb2eb',
61+
'blue-lighter': '#bcdefa',
62+
'blue-lightest': '#eff8ff',
7063

71-
'purple-darkest': '#21183c',
72-
'purple-darker': '#382b5f',
73-
'purple-dark': '#794acf',
74-
purple: '#9561e2',
75-
'purple-light': '#a779e9',
76-
'purple-lighter': '#d6bbfc',
77-
'purple-lightest': '#f3ebff',
64+
'indigo-darkest': '#191e38',
65+
'indigo-darker': '#2f365f',
66+
'indigo-dark': '#5661b3',
67+
indigo: '#6574cd',
68+
'indigo-light': '#7886d7',
69+
'indigo-lighter': '#b2b7ff',
70+
'indigo-lightest': '#e6e8ff',
7871

79-
'pink-darkest': '#451225',
80-
'pink-darker': '#6f213f',
81-
'pink-dark': '#eb5286',
82-
pink: '#f66d9b',
83-
'pink-light': '#fa7ea8',
84-
'pink-lighter': '#ffbbca',
85-
'pink-lightest': '#ffebef',
86-
}
72+
'purple-darkest': '#21183c',
73+
'purple-darker': '#382b5f',
74+
'purple-dark': '#794acf',
75+
purple: '#9561e2',
76+
'purple-light': '#a779e9',
77+
'purple-lighter': '#d6bbfc',
78+
'purple-lightest': '#f3ebff',
8779

88-
return {
89-
colors,
80+
'pink-darkest': '#451225',
81+
'pink-darker': '#6f213f',
82+
'pink-dark': '#eb5286',
83+
pink: '#f66d9b',
84+
'pink-light': '#fa7ea8',
85+
'pink-lighter': '#ffbbca',
86+
'pink-lightest': '#ffebef',
87+
},
9088
screens: {
9189
sm: '576px',
9290
md: '768px',
@@ -155,8 +153,8 @@ module.exports = function() {
155153
normal: '0',
156154
wide: '0.05em',
157155
},
158-
textColors: colors,
159-
backgroundColors: colors,
156+
textColors: theme => theme.colors,
157+
backgroundColors: theme => theme.colors,
160158
backgroundSize: {
161159
auto: 'auto',
162160
cover: 'cover',
@@ -169,7 +167,9 @@ module.exports = function() {
169167
'4': '4px',
170168
'8': '8px',
171169
},
172-
borderColors: global.Object.assign({ default: colors['grey-light'] }, colors),
170+
borderColors: theme => {
171+
return global.Object.assign({ default: theme.colors['grey-light'] }, theme.colors)
172+
},
173173
borderRadius: {
174174
none: '0',
175175
sm: '.125rem',

0 commit comments

Comments
 (0)