diff --git a/__tests__/applyAtRule.test.js b/__tests__/applyAtRule.test.js index b84c4588b..a099f1d86 100644 --- a/__tests__/applyAtRule.test.js +++ b/__tests__/applyAtRule.test.js @@ -1,10 +1,14 @@ import postcss from 'postcss' import substituteClassApplyAtRules from '../src/lib/substituteClassApplyAtRules' import processPlugins from '../src/util/processPlugins' +import resolveConfig from '../src/util/resolveConfig' import corePlugins from '../src/corePlugins' import defaultConfig from '../defaultConfig.stub.js' -const { utilities: defaultUtilities } = processPlugins(corePlugins(defaultConfig), defaultConfig) +const { utilities: defaultUtilities } = processPlugins( + corePlugins(resolveConfig([defaultConfig])), + defaultConfig +) function run(input, config = defaultConfig, utilities = defaultUtilities) { return postcss([substituteClassApplyAtRules(config, utilities)]).process(input, { @@ -200,10 +204,12 @@ test('you can apply utility classes without using the given prefix', () => { .foo { margin-top: 1rem; margin-bottom: 1rem; } ` - const config = { - ...defaultConfig, - prefix: 'tw-', - } + const config = resolveConfig([ + { + ...defaultConfig, + prefix: 'tw-', + }, + ]) return run(input, config, processPlugins(corePlugins(config), config).utilities).then(result => { expect(result.css).toEqual(expected) @@ -220,12 +226,14 @@ test('you can apply utility classes without using the given prefix when using a .foo { margin-top: 1rem; margin-bottom: 1rem; } ` - const config = { - ...defaultConfig, - prefix: () => { - return 'tw-' + const config = resolveConfig([ + { + ...defaultConfig, + prefix: () => { + return 'tw-' + }, }, - } + ]) return run(input, config, processPlugins(corePlugins(config), config).utilities).then(result => { expect(result.css).toEqual(expected) diff --git a/__tests__/fixtures/tailwind-output-important.css b/__tests__/fixtures/tailwind-output-important.css index 5c9374c30..54e50fe20 100644 --- a/__tests__/fixtures/tailwind-output-important.css +++ b/__tests__/fixtures/tailwind-output-important.css @@ -3005,6 +3005,10 @@ table { font-weight: 900 !important; } +.h-0 { + height: 0 !important; +} + .h-1 { height: .25rem !important; } @@ -3045,6 +3049,10 @@ table { height: 4rem !important; } +.h-20 { + height: 5rem !important; +} + .h-24 { height: 6rem !important; } @@ -5949,6 +5957,10 @@ table { white-space: nowrap !important; } +.w-0 { + width: 0 !important; +} + .w-1 { width: .25rem !important; } @@ -5989,6 +6001,10 @@ table { width: 4rem !important; } +.w-20 { + width: 5rem !important; +} + .w-24 { width: 6rem !important; } @@ -8590,6 +8606,10 @@ table { font-weight: 900 !important; } + .sm\:h-0 { + height: 0 !important; + } + .sm\:h-1 { height: .25rem !important; } @@ -8630,6 +8650,10 @@ table { height: 4rem !important; } + .sm\:h-20 { + height: 5rem !important; + } + .sm\:h-24 { height: 6rem !important; } @@ -11518,6 +11542,10 @@ table { white-space: nowrap !important; } + .sm\:w-0 { + width: 0 !important; + } + .sm\:w-1 { width: .25rem !important; } @@ -11558,6 +11586,10 @@ table { width: 4rem !important; } + .sm\:w-20 { + width: 5rem !important; + } + .sm\:w-24 { width: 6rem !important; } @@ -14160,6 +14192,10 @@ table { font-weight: 900 !important; } + .md\:h-0 { + height: 0 !important; + } + .md\:h-1 { height: .25rem !important; } @@ -14200,6 +14236,10 @@ table { height: 4rem !important; } + .md\:h-20 { + height: 5rem !important; + } + .md\:h-24 { height: 6rem !important; } @@ -17088,6 +17128,10 @@ table { white-space: nowrap !important; } + .md\:w-0 { + width: 0 !important; + } + .md\:w-1 { width: .25rem !important; } @@ -17128,6 +17172,10 @@ table { width: 4rem !important; } + .md\:w-20 { + width: 5rem !important; + } + .md\:w-24 { width: 6rem !important; } @@ -19730,6 +19778,10 @@ table { font-weight: 900 !important; } + .lg\:h-0 { + height: 0 !important; + } + .lg\:h-1 { height: .25rem !important; } @@ -19770,6 +19822,10 @@ table { height: 4rem !important; } + .lg\:h-20 { + height: 5rem !important; + } + .lg\:h-24 { height: 6rem !important; } @@ -22658,6 +22714,10 @@ table { white-space: nowrap !important; } + .lg\:w-0 { + width: 0 !important; + } + .lg\:w-1 { width: .25rem !important; } @@ -22698,6 +22758,10 @@ table { width: 4rem !important; } + .lg\:w-20 { + width: 5rem !important; + } + .lg\:w-24 { width: 6rem !important; } @@ -25300,6 +25364,10 @@ table { font-weight: 900 !important; } + .xl\:h-0 { + height: 0 !important; + } + .xl\:h-1 { height: .25rem !important; } @@ -25340,6 +25408,10 @@ table { height: 4rem !important; } + .xl\:h-20 { + height: 5rem !important; + } + .xl\:h-24 { height: 6rem !important; } @@ -28228,6 +28300,10 @@ table { white-space: nowrap !important; } + .xl\:w-0 { + width: 0 !important; + } + .xl\:w-1 { width: .25rem !important; } @@ -28268,6 +28344,10 @@ table { width: 4rem !important; } + .xl\:w-20 { + width: 5rem !important; + } + .xl\:w-24 { width: 6rem !important; } diff --git a/__tests__/fixtures/tailwind-output.css b/__tests__/fixtures/tailwind-output.css index 16c475e17..bc9009f76 100644 --- a/__tests__/fixtures/tailwind-output.css +++ b/__tests__/fixtures/tailwind-output.css @@ -3005,6 +3005,10 @@ table { font-weight: 900; } +.h-0 { + height: 0; +} + .h-1 { height: .25rem; } @@ -3045,6 +3049,10 @@ table { height: 4rem; } +.h-20 { + height: 5rem; +} + .h-24 { height: 6rem; } @@ -5949,6 +5957,10 @@ table { white-space: nowrap; } +.w-0 { + width: 0; +} + .w-1 { width: .25rem; } @@ -5989,6 +6001,10 @@ table { width: 4rem; } +.w-20 { + width: 5rem; +} + .w-24 { width: 6rem; } @@ -8590,6 +8606,10 @@ table { font-weight: 900; } + .sm\:h-0 { + height: 0; + } + .sm\:h-1 { height: .25rem; } @@ -8630,6 +8650,10 @@ table { height: 4rem; } + .sm\:h-20 { + height: 5rem; + } + .sm\:h-24 { height: 6rem; } @@ -11518,6 +11542,10 @@ table { white-space: nowrap; } + .sm\:w-0 { + width: 0; + } + .sm\:w-1 { width: .25rem; } @@ -11558,6 +11586,10 @@ table { width: 4rem; } + .sm\:w-20 { + width: 5rem; + } + .sm\:w-24 { width: 6rem; } @@ -14160,6 +14192,10 @@ table { font-weight: 900; } + .md\:h-0 { + height: 0; + } + .md\:h-1 { height: .25rem; } @@ -14200,6 +14236,10 @@ table { height: 4rem; } + .md\:h-20 { + height: 5rem; + } + .md\:h-24 { height: 6rem; } @@ -17088,6 +17128,10 @@ table { white-space: nowrap; } + .md\:w-0 { + width: 0; + } + .md\:w-1 { width: .25rem; } @@ -17128,6 +17172,10 @@ table { width: 4rem; } + .md\:w-20 { + width: 5rem; + } + .md\:w-24 { width: 6rem; } @@ -19730,6 +19778,10 @@ table { font-weight: 900; } + .lg\:h-0 { + height: 0; + } + .lg\:h-1 { height: .25rem; } @@ -19770,6 +19822,10 @@ table { height: 4rem; } + .lg\:h-20 { + height: 5rem; + } + .lg\:h-24 { height: 6rem; } @@ -22658,6 +22714,10 @@ table { white-space: nowrap; } + .lg\:w-0 { + width: 0; + } + .lg\:w-1 { width: .25rem; } @@ -22698,6 +22758,10 @@ table { width: 4rem; } + .lg\:w-20 { + width: 5rem; + } + .lg\:w-24 { width: 6rem; } @@ -25300,6 +25364,10 @@ table { font-weight: 900; } + .xl\:h-0 { + height: 0; + } + .xl\:h-1 { height: .25rem; } @@ -25340,6 +25408,10 @@ table { height: 4rem; } + .xl\:h-20 { + height: 5rem; + } + .xl\:h-24 { height: 6rem; } @@ -28228,6 +28300,10 @@ table { white-space: nowrap; } + .xl\:w-0 { + width: 0; + } + .xl\:w-1 { width: .25rem; } @@ -28268,6 +28344,10 @@ table { width: 4rem; } + .xl\:w-20 { + width: 5rem; + } + .xl\:w-24 { width: 6rem; } diff --git a/__tests__/variantsAtRule.test.js b/__tests__/variantsAtRule.test.js index cce5e2572..d0b20e4fc 100644 --- a/__tests__/variantsAtRule.test.js +++ b/__tests__/variantsAtRule.test.js @@ -218,6 +218,33 @@ test('variants are generated in the order specified', () => { }) }) +test('the default variant can be generated in a specified position', () => { + const input = ` + @variants focus, active, default, hover { + .banana { color: yellow; } + .chocolate { color: brown; } + } + ` + + const output = ` + .focus\\:banana:focus { color: yellow; } + .focus\\:chocolate:focus { color: brown; } + .active\\:banana:active { color: yellow; } + .active\\:chocolate:active { color: brown; } + .banana { color: yellow; } + .chocolate { color: brown; } + .hover\\:banana:hover { color: yellow; } + .hover\\:chocolate:hover { color: brown; } + ` + + return run(input, { + ...config, + }).then(result => { + expect(result.css).toMatchCss(output) + expect(result.warnings().length).toBe(0) + }) +}) + test('plugin variants can modify rules using the raw PostCSS API', () => { const input = ` @variants important { diff --git a/defaultTheme.js b/defaultTheme.js index cf6304099..4137a4209 100644 --- a/defaultTheme.js +++ b/defaultTheme.js @@ -85,6 +85,23 @@ module.exports = function() { 'pink-lighter': '#ffbbca', 'pink-lightest': '#ffebef', }, + spacing: { + px: '1px', + '0': '0', + '1': '0.25rem', + '2': '0.5rem', + '3': '0.75rem', + '4': '1rem', + '5': '1.25rem', + '6': '1.5rem', + '8': '2rem', + '10': '2.5rem', + '12': '3rem', + '16': '4rem', + '20': '5rem', + '24': '6rem', + '32': '8rem', + }, screens: { sm: '576px', md: '768px', @@ -188,21 +205,9 @@ module.exports = function() { lg: '.5rem', full: '9999px', }, - width: { + width: theme => ({ auto: 'auto', - px: '1px', - '1': '0.25rem', - '2': '0.5rem', - '3': '0.75rem', - '4': '1rem', - '5': '1.25rem', - '6': '1.5rem', - '8': '2rem', - '10': '2.5rem', - '12': '3rem', - '16': '4rem', - '24': '6rem', - '32': '8rem', + ...theme.spacing, '48': '12rem', '64': '16rem', '1/2': '50%', @@ -218,27 +223,15 @@ module.exports = function() { '5/6': '83.33333%', full: '100%', screen: '100vw', - }, - height: { + }), + height: theme => ({ auto: 'auto', - px: '1px', - '1': '0.25rem', - '2': '0.5rem', - '3': '0.75rem', - '4': '1rem', - '5': '1.25rem', - '6': '1.5rem', - '8': '2rem', - '10': '2.5rem', - '12': '3rem', - '16': '4rem', - '24': '6rem', - '32': '8rem', + ...theme.spacing, '48': '12rem', '64': '16rem', full: '100%', screen: '100vh', - }, + }), minWidth: { '0': '0', full: '100%', @@ -264,58 +257,9 @@ module.exports = function() { full: '100%', screen: '100vh', }, - padding: { - px: '1px', - '0': '0', - '1': '0.25rem', - '2': '0.5rem', - '3': '0.75rem', - '4': '1rem', - '5': '1.25rem', - '6': '1.5rem', - '8': '2rem', - '10': '2.5rem', - '12': '3rem', - '16': '4rem', - '20': '5rem', - '24': '6rem', - '32': '8rem', - }, - margin: { - auto: 'auto', - px: '1px', - '0': '0', - '1': '0.25rem', - '2': '0.5rem', - '3': '0.75rem', - '4': '1rem', - '5': '1.25rem', - '6': '1.5rem', - '8': '2rem', - '10': '2.5rem', - '12': '3rem', - '16': '4rem', - '20': '5rem', - '24': '6rem', - '32': '8rem', - }, - negativeMargin: { - px: '1px', - '0': '0', - '1': '0.25rem', - '2': '0.5rem', - '3': '0.75rem', - '4': '1rem', - '5': '1.25rem', - '6': '1.5rem', - '8': '2rem', - '10': '2.5rem', - '12': '3rem', - '16': '4rem', - '20': '5rem', - '24': '6rem', - '32': '8rem', - }, + padding: theme => theme.spacing, + margin: theme => ({ auto: 'auto', ...theme.spacing }), + negativeMargin: theme => theme.spacing, boxShadow: { default: '0 2px 4px 0 rgba(0,0,0,0.10)', md: '0 4px 8px 0 rgba(0,0,0,0.12), 0 2px 4px 0 rgba(0,0,0,0.08)', diff --git a/src/lib/substituteVariantsAtRules.js b/src/lib/substituteVariantsAtRules.js index 01704da04..a586a66ec 100644 --- a/src/lib/substituteVariantsAtRules.js +++ b/src/lib/substituteVariantsAtRules.js @@ -10,7 +10,12 @@ function generatePseudoClassVariant(pseudoClass) { }) } +function ensureIncludesDefault(variants) { + return variants.includes('default') ? variants : ['default', ...variants] +} + const defaultVariantGenerators = { + default: generateVariantFunction(() => {}), 'group-hover': generateVariantFunction(({ modifySelectors, separator }) => { return modifySelectors(({ className }) => { return `.group:hover .group-hover${separator}${className}` @@ -38,9 +43,7 @@ export default function(config, { variantGenerators: pluginVariantGenerators }) responsiveParent.append(atRule) } - atRule.before(atRule.clone().nodes) - - _.forEach(_.without(variants, 'responsive'), variant => { + _.forEach(_.without(ensureIncludesDefault(variants), 'responsive'), variant => { variantGenerators[variant](atRule, config) })