From 85ea38b2f54fe39f0517107cd6a9697146190e7c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benoi=CC=82t=20Rouleau?= Date: Wed, 2 Jan 2019 17:32:02 -0500 Subject: [PATCH 1/8] Add ability to configure background position utilities --- defaultConfig.stub.js | 27 +++++++++++++++++++++++++++ src/generators/backgroundPosition.js | 19 +++++++------------ 2 files changed, 34 insertions(+), 12 deletions(-) diff --git a/defaultConfig.stub.js b/defaultConfig.stub.js index 974da5ad8..5cac850b8 100644 --- a/defaultConfig.stub.js +++ b/defaultConfig.stub.js @@ -367,6 +367,33 @@ module.exports = { backgroundColors: colors, + /* + |----------------------------------------------------------------------------- + | Background positions https://tailwindcss.com/docs/background-positions + |----------------------------------------------------------------------------- + | + | Here is where you define your background positions. We provide some + | common values that are useful in most projects, but feel free to add + | other positions that are specific to your project here as well. + | + | Class name: .bg-{position} + | CSS property: background-position + | + */ + + backgroundPosition: { + 'bottom': 'bottom', + 'center': 'center', + 'left': 'left', + 'left-bottom': 'left bottom', + 'left-top': 'left top', + 'right': 'right', + 'right-bottom': 'right bottom', + 'right-top': 'right top', + 'top': 'top', + }, + + /* |----------------------------------------------------------------------------- | Background sizes https://tailwindcss.com/docs/background-size diff --git a/src/generators/backgroundPosition.js b/src/generators/backgroundPosition.js index 1a1f9b93a..b069a7b0e 100644 --- a/src/generators/backgroundPosition.js +++ b/src/generators/backgroundPosition.js @@ -1,15 +1,10 @@ -import defineClasses from '../util/defineClasses' +import _ from 'lodash' +import defineClass from '../util/defineClass' -export default function() { - return defineClasses({ - 'bg-bottom': { 'background-position': 'bottom' }, - 'bg-center': { 'background-position': 'center' }, - 'bg-left': { 'background-position': 'left' }, - 'bg-left-bottom': { 'background-position': 'left bottom' }, - 'bg-left-top': { 'background-position': 'left top' }, - 'bg-right': { 'background-position': 'right' }, - 'bg-right-bottom': { 'background-position': 'right bottom' }, - 'bg-right-top': { 'background-position': 'right top' }, - 'bg-top': { 'background-position': 'top' }, +export default function({ backgroundPosition }) { + return _.map(backgroundPosition, (position, className) => { + return defineClass(`bg-${className}`, { + 'background-position': position, + }) }) } From 9f8bf54e8ee5993e97f65df02c93acbfdf8a28c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benoi=CC=82t=20Rouleau?= Date: Wed, 2 Jan 2019 17:35:39 -0500 Subject: [PATCH 2/8] Fix URL --- defaultConfig.stub.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/defaultConfig.stub.js b/defaultConfig.stub.js index 5cac850b8..106fc7ee3 100644 --- a/defaultConfig.stub.js +++ b/defaultConfig.stub.js @@ -369,7 +369,7 @@ module.exports = { /* |----------------------------------------------------------------------------- - | Background positions https://tailwindcss.com/docs/background-positions + | Background positions https://tailwindcss.com/docs/background-position |----------------------------------------------------------------------------- | | Here is where you define your background positions. We provide some From 3785a9cda664b638b0bdf8e38af4a10d8212660a Mon Sep 17 00:00:00 2001 From: Justin Anastos Date: Tue, 5 Feb 2019 09:39:32 -0500 Subject: [PATCH 3/8] Add test for nested atRules in responsiveAtRule --- __tests__/responsiveAtRule.test.js | 108 +++++++++++++++++++++++++++++ 1 file changed, 108 insertions(+) diff --git a/__tests__/responsiveAtRule.test.js b/__tests__/responsiveAtRule.test.js index c13240a67..4b1d4509e 100644 --- a/__tests__/responsiveAtRule.test.js +++ b/__tests__/responsiveAtRule.test.js @@ -6,6 +6,114 @@ function run(input, opts = config) { return postcss([plugin(opts)]).process(input, { from: undefined }) } +test('it can generate responsive variants for nested at rules', () => { + const input = ` + @responsive { + .banana { color: yellow; } + .chocolate { color: brown; } + + @supports(display: grid) { + .grid\\:banana { color: blue; } + .grid\\:chocolate { color: green; } + } + } + ` + + const output = ` + .banana { + color: yellow; + } + + .chocolate { + color: brown; + } + + @supports(display: grid) { + .grid\\:banana { + color: blue; + } + + .grid\\:chocolate { + color: green; + } + } + + @media (min-width: 500px) { + .sm\\:banana { + color: yellow; + } + + .sm\\:chocolate { + color: brown; + } + + @supports(display: grid) { + .sm\\:grid\\:banana { + color: blue; + } + + .sm\\:grid\\:chocolate { + color: green; + } + } + } + + @media (min-width: 750px) { + .md\\:banana { + color: yellow; + } + + .md\\:chocolate { + color: brown; + } + + @supports(display: grid) { + .md\\:grid\\:banana { + color: blue; + } + + .md\\:grid\\:chocolate { + color: green; + } + } + } + + @media (min-width: 1000px) { + .lg\\:banana { + color: yellow; + } + + .lg\\:chocolate { + color: brown; + } + + @supports(display: grid) { + .lg\\:grid\\:banana { + color: blue; + } + + .lg\\:grid\\:chocolate { + color: green; + } + } + } + ` + + return run(input, { + screens: { + sm: '500px', + md: '750px', + lg: '1000px', + }, + options: { + separator: ':', + }, + }).then(result => { + expect(result.css).toMatchCss(output) + expect(result.warnings().length).toBe(0) + }) +}) + test('it can generate responsive variants', () => { const input = ` @responsive { From 40bb6c619d465a2b6fb41cd625f168eedf85dd03 Mon Sep 17 00:00:00 2001 From: Justin Anastos Date: Tue, 5 Feb 2019 09:00:27 -0500 Subject: [PATCH 4/8] Add nested atRule support to substituteResponsiveAtRules --- src/lib/substituteResponsiveAtRules.js | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/src/lib/substituteResponsiveAtRules.js b/src/lib/substituteResponsiveAtRules.js index 95762c310..ca04fa92a 100644 --- a/src/lib/substituteResponsiveAtRules.js +++ b/src/lib/substituteResponsiveAtRules.js @@ -25,7 +25,8 @@ export default function(config) { }) mediaQuery.append( - responsiveRules.map(rule => { + // Filter out nested `atRules`; we'll process those separately + responsiveRules.filter(rule => rule.type !== 'atrule').map(rule => { const cloned = rule.clone() cloned.selectors = _.map(rule.selectors, selector => buildSelectorVariant(selector, screen, separator, message => { @@ -36,6 +37,22 @@ export default function(config) { }) ) + mediaQuery.append( + // Process nested `atRules`. + responsiveRules.filter(rule => rule.type === 'atrule').map(atRule => { + const clonedAtRule = atRule.clone() + clonedAtRule.nodes.forEach(rule => { + rule.selectors = _.map(rule.selectors, selector => { + const selectorVariant = buildSelectorVariant(selector, screen, separator, message => { + throw rule.error(message) + }) + return selectorVariant + }) + }) + return clonedAtRule + }) + ) + finalRules.push(mediaQuery) }) From faf2be163fd71ea84f723e3e0e396e7a1396363f Mon Sep 17 00:00:00 2001 From: Adam Wathan Date: Wed, 6 Feb 2019 08:29:25 -0500 Subject: [PATCH 5/8] Add failing test for using @responsive with deeply nested at-rules --- __tests__/responsiveAtRule.test.js | 238 ++++++++++++++++------------- 1 file changed, 130 insertions(+), 108 deletions(-) diff --git a/__tests__/responsiveAtRule.test.js b/__tests__/responsiveAtRule.test.js index 4b1d4509e..da9a411d1 100644 --- a/__tests__/responsiveAtRule.test.js +++ b/__tests__/responsiveAtRule.test.js @@ -6,114 +6,6 @@ function run(input, opts = config) { return postcss([plugin(opts)]).process(input, { from: undefined }) } -test('it can generate responsive variants for nested at rules', () => { - const input = ` - @responsive { - .banana { color: yellow; } - .chocolate { color: brown; } - - @supports(display: grid) { - .grid\\:banana { color: blue; } - .grid\\:chocolate { color: green; } - } - } - ` - - const output = ` - .banana { - color: yellow; - } - - .chocolate { - color: brown; - } - - @supports(display: grid) { - .grid\\:banana { - color: blue; - } - - .grid\\:chocolate { - color: green; - } - } - - @media (min-width: 500px) { - .sm\\:banana { - color: yellow; - } - - .sm\\:chocolate { - color: brown; - } - - @supports(display: grid) { - .sm\\:grid\\:banana { - color: blue; - } - - .sm\\:grid\\:chocolate { - color: green; - } - } - } - - @media (min-width: 750px) { - .md\\:banana { - color: yellow; - } - - .md\\:chocolate { - color: brown; - } - - @supports(display: grid) { - .md\\:grid\\:banana { - color: blue; - } - - .md\\:grid\\:chocolate { - color: green; - } - } - } - - @media (min-width: 1000px) { - .lg\\:banana { - color: yellow; - } - - .lg\\:chocolate { - color: brown; - } - - @supports(display: grid) { - .lg\\:grid\\:banana { - color: blue; - } - - .lg\\:grid\\:chocolate { - color: green; - } - } - } - ` - - return run(input, { - screens: { - sm: '500px', - md: '750px', - lg: '1000px', - }, - options: { - separator: ':', - }, - }).then(result => { - expect(result.css).toMatchCss(output) - expect(result.warnings().length).toBe(0) - }) -}) - test('it can generate responsive variants', () => { const input = ` @responsive { @@ -280,6 +172,136 @@ test('responsive variants are grouped', () => { }) }) +test('it can generate responsive variants for nested at-rules', () => { + const input = ` + @responsive { + .banana { color: yellow; } + + @supports(display: grid) { + .grid\\:banana { color: blue; } + } + } + ` + + const output = ` + .banana { + color: yellow; + } + + @supports(display: grid) { + .grid\\:banana { + color: blue; + } + } + + @media (min-width: 500px) { + .sm\\:banana { + color: yellow; + } + + @supports(display: grid) { + .sm\\:grid\\:banana { + color: blue; + } + } + } + + @media (min-width: 1000px) { + .lg\\:banana { + color: yellow; + } + + @supports(display: grid) { + .lg\\:grid\\:banana { + color: blue; + } + } + } + ` + + return run(input, { + screens: { + sm: '500px', + lg: '1000px', + }, + options: { + separator: ':', + }, + }).then(result => { + expect(result.css).toMatchCss(output) + expect(result.warnings().length).toBe(0) + }) +}) + +test.only('it can generate responsive variants for deeply nested at-rules', () => { + const input = ` + @responsive { + .banana { color: yellow; } + + @supports(display: grid) { + @supports(display: flex) { + .flex-grid\\:banana { color: blue; } + } + } + } + ` + + const output = ` + .banana { + color: yellow; + } + + @supports(display: grid) { + @supports(display: flex) { + .flex-grid\\:banana { + color: blue; + } + } + } + + @media (min-width: 500px) { + .sm\\:banana { + color: yellow; + } + + @supports(display: grid) { + @supports(display: flex) { + .sm\\:flex-grid\\:banana { + color: blue; + } + } + } + } + + @media (min-width: 1000px) { + .lg\\:banana { + color: yellow; + } + + @supports(display: grid) { + @supports(display: flex) { + .lg\\:flex-grid\\:banana { + color: blue; + } + } + } + } + ` + + return run(input, { + screens: { + sm: '500px', + lg: '1000px', + }, + options: { + separator: ':', + }, + }).then(result => { + expect(result.css).toMatchCss(output) + expect(result.warnings().length).toBe(0) + }) +}) + test('screen prefix is only applied to the last class in a selector', () => { const input = ` @responsive { From b544febfcbb27a63b0eae755accc58ef23b5a7c7 Mon Sep 17 00:00:00 2001 From: Adam Wathan Date: Wed, 6 Feb 2019 14:20:03 -0500 Subject: [PATCH 6/8] Use root instead of array to unify code paths --- __tests__/responsiveAtRule.test.js | 2 +- src/lib/substituteResponsiveAtRules.js | 31 +++++--------------------- 2 files changed, 7 insertions(+), 26 deletions(-) diff --git a/__tests__/responsiveAtRule.test.js b/__tests__/responsiveAtRule.test.js index da9a411d1..42babf4bf 100644 --- a/__tests__/responsiveAtRule.test.js +++ b/__tests__/responsiveAtRule.test.js @@ -233,7 +233,7 @@ test('it can generate responsive variants for nested at-rules', () => { }) }) -test.only('it can generate responsive variants for deeply nested at-rules', () => { +test('it can generate responsive variants for deeply nested at-rules', () => { const input = ` @responsive { .banana { color: yellow; } diff --git a/src/lib/substituteResponsiveAtRules.js b/src/lib/substituteResponsiveAtRules.js index ca04fa92a..71c352410 100644 --- a/src/lib/substituteResponsiveAtRules.js +++ b/src/lib/substituteResponsiveAtRules.js @@ -8,12 +8,12 @@ export default function(config) { return function(css) { const screens = config.screens const separator = config.options.separator - const responsiveRules = [] + const responsiveRules = postcss.root() let finalRules = [] css.walkAtRules('responsive', atRule => { const nodes = atRule.nodes - responsiveRules.push(...cloneNodes(nodes)) + responsiveRules.append(...cloneNodes(nodes)) atRule.before(nodes) atRule.remove() }) @@ -24,34 +24,15 @@ export default function(config) { params: buildMediaQuery(screens[screen]), }) - mediaQuery.append( - // Filter out nested `atRules`; we'll process those separately - responsiveRules.filter(rule => rule.type !== 'atrule').map(rule => { - const cloned = rule.clone() - cloned.selectors = _.map(rule.selectors, selector => + mediaQuery.append(_.tap(responsiveRules.clone(), clonedRoot => { + clonedRoot.walkRules(rule => { + rule.selectors = _.map(rule.selectors, selector => buildSelectorVariant(selector, screen, separator, message => { throw rule.error(message) }) ) - return cloned }) - ) - - mediaQuery.append( - // Process nested `atRules`. - responsiveRules.filter(rule => rule.type === 'atrule').map(atRule => { - const clonedAtRule = atRule.clone() - clonedAtRule.nodes.forEach(rule => { - rule.selectors = _.map(rule.selectors, selector => { - const selectorVariant = buildSelectorVariant(selector, screen, separator, message => { - throw rule.error(message) - }) - return selectorVariant - }) - }) - return clonedAtRule - }) - ) + })) finalRules.push(mediaQuery) }) From 8aabccb8d40b3f2ede1865da3d7ed5afa8d372bf Mon Sep 17 00:00:00 2001 From: Adam Wathan Date: Wed, 6 Feb 2019 14:29:05 -0500 Subject: [PATCH 7/8] Fix code style --- src/lib/substituteResponsiveAtRules.js | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/src/lib/substituteResponsiveAtRules.js b/src/lib/substituteResponsiveAtRules.js index 71c352410..9bac7d59c 100644 --- a/src/lib/substituteResponsiveAtRules.js +++ b/src/lib/substituteResponsiveAtRules.js @@ -24,15 +24,17 @@ export default function(config) { params: buildMediaQuery(screens[screen]), }) - mediaQuery.append(_.tap(responsiveRules.clone(), clonedRoot => { - clonedRoot.walkRules(rule => { - rule.selectors = _.map(rule.selectors, selector => - buildSelectorVariant(selector, screen, separator, message => { - throw rule.error(message) - }) - ) + mediaQuery.append( + _.tap(responsiveRules.clone(), clonedRoot => { + clonedRoot.walkRules(rule => { + rule.selectors = _.map(rule.selectors, selector => + buildSelectorVariant(selector, screen, separator, message => { + throw rule.error(message) + }) + ) + }) }) - })) + ) finalRules.push(mediaQuery) }) From 0de9df3de987cd2df287bcfda8da3dd758219748 Mon Sep 17 00:00:00 2001 From: Adam Wathan Date: Thu, 7 Feb 2019 09:12:24 -0500 Subject: [PATCH 8/8] Use correct variant config for backgroundSize plugin --- src/plugins/backgroundSize.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/backgroundSize.js b/src/plugins/backgroundSize.js index 80bd9eec4..f3d96fd59 100644 --- a/src/plugins/backgroundSize.js +++ b/src/plugins/backgroundSize.js @@ -13,6 +13,6 @@ export default function() { }) ) - addUtilities(utilities, config('modules.opacity')) + addUtilities(utilities, config('modules.backgroundSize')) } }