diff --git a/__tests__/prefixTree.test.js b/__tests__/prefixTree.test.js index cd3029fb4..29f019122 100644 --- a/__tests__/prefixTree.test.js +++ b/__tests__/prefixTree.test.js @@ -29,6 +29,7 @@ test('it handles a function as the prefix', () => { ` const prefixFunc = selector => { + return selector === '.foo' ? 'tw-' : '' if (selector === '.foo') { return 'tw-' } @@ -40,3 +41,17 @@ test('it handles a function as the prefix', () => { expect(result.css).toEqual(expected) expect(result.warnings().length).toBe(0) }) + +test('it prefixes all classes in a selector', () => { + const input = postcss.parse(` + .btn-blue .w-1\\/4 > h1.text-xl + a .bar { color: red; } + `) + + const expected = ` + .tw-btn-blue .tw-w-1\\/4 > h1.tw-text-xl + a .tw-bar { color: red; } + ` + + const result = prefixTree(input, 'tw-').toResult() + expect(result.css).toEqual(expected) + expect(result.warnings().length).toBe(0) +}) diff --git a/__tests__/processPlugins.test.js b/__tests__/processPlugins.test.js index 2c37c99bf..1f1572504 100644 --- a/__tests__/processPlugins.test.js +++ b/__tests__/processPlugins.test.js @@ -755,3 +755,26 @@ test('variants can still be specified when ignoring prefix and important options } `) }) + +test('prefix will prefix all classes in a selector', () => { + const [components] = processPluginsWithValidConfig({ + plugins: [ + function({ addComponents, prefix }) { + addComponents({ + [prefix('.btn-blue .w-1\\/4 > h1.text-xl + a .bar')]: { + backgroundColor: 'blue', + }, + }) + }, + ], + options: { + prefix: 'tw-', + }, + }) + + expect(css(components)).toMatchCss(` + .tw-btn-blue .tw-w-1\\/4 > h1.tw-text-xl + a .tw-bar { + background-color: blue + } + `) +}) diff --git a/package.json b/package.json index 0952cccd5..3f904cc88 100644 --- a/package.json +++ b/package.json @@ -50,7 +50,8 @@ "postcss": "^6.0.9", "postcss-functions": "^3.0.0", "postcss-js": "^1.0.1", - "postcss-nested": "^3.0.0" + "postcss-nested": "^3.0.0", + "postcss-selector-parser": "^3.1.1" }, "browserslist": [ "> 1%" diff --git a/src/util/prefixSelector.js b/src/util/prefixSelector.js index a5133abe7..1c42816be 100644 --- a/src/util/prefixSelector.js +++ b/src/util/prefixSelector.js @@ -1,5 +1,11 @@ +import parser from 'postcss-selector-parser' + export default function(prefix, selector) { const getPrefix = typeof prefix === 'function' ? prefix : () => prefix - return `.${getPrefix(selector)}${selector.slice(1)}` + return parser(selectors => { + selectors.walkClasses((classSelector) => { + classSelector.value = `${getPrefix('.' + classSelector.value)}${classSelector.value}` + }) + }).processSync(selector) }