diff --git a/__tests__/applyAtRule.test.js b/__tests__/applyAtRule.test.js index 06d2a4416..8ad5af4dc 100644 --- a/__tests__/applyAtRule.test.js +++ b/__tests__/applyAtRule.test.js @@ -14,11 +14,36 @@ test("it copies a class's declarations into itself", () => { }) }) -test('it removes important from applied classes', () => { - const output = '.a { color: red !important; } .b { color: red; }' +test('it removes important from applied classes by default', () => { + const input = ` + .a { color: red !important; } + .b { @apply .a; } + ` - return run('.a { color: red !important; } .b { @apply .a; }').then(result => { - expect(result.css).toEqual(output) + const expected = ` + .a { color: red !important; } + .b { color: red; } + ` + + return run(input).then(result => { + expect(result.css).toEqual(expected) + expect(result.warnings().length).toBe(0) + }) +}) + +test('applied rules can be made !important', () => { + const input = ` + .a { color: red; } + .b { @apply .a !important; } + ` + + const expected = ` + .a { color: red; } + .b { color: red !important; } + ` + + return run(input).then(result => { + expect(result.css).toEqual(expected) expect(result.warnings().length).toBe(0) }) }) diff --git a/src/lib/substituteClassApplyAtRules.js b/src/lib/substituteClassApplyAtRules.js index 48935c9ef..35a5b4bf0 100644 --- a/src/lib/substituteClassApplyAtRules.js +++ b/src/lib/substituteClassApplyAtRules.js @@ -2,10 +2,8 @@ import _ from 'lodash' import postcss from 'postcss' import escapeClassName from '../util/escapeClassName' -function normalizeClassNames(classNames) { - return classNames.map(className => { - return `.${escapeClassName(_.trimStart(className, '.'))}` - }) +function normalizeClassName(className) { + return `.${escapeClassName(_.trimStart(className, '.'))}` } function findMixin(css, mixin, onError) { @@ -52,14 +50,17 @@ export default function() { return _.startsWith(mixin, '--') }) - const decls = _.flatMap(normalizeClassNames(classes), mixin => { - return findMixin(css, mixin, message => { - throw atRule.error(message) + const decls = _(classes) + .reject(mixin => mixin === '!important') + .flatMap(mixin => { + return findMixin(css, normalizeClassName(mixin), message => { + throw atRule.error(message) + }) }) - }) + .value() - decls.forEach(decl => { - decl.important = false + _.tap(_.last(mixins) === '!important', important => { + decls.forEach(decl => (decl.important = important)) }) atRule.before(decls)