Merge pull request #309 from tailwindcss/apply-important
Add support for applying classes as `!important`
This commit is contained in:
commit
d146b996aa
3 changed files with 103 additions and 15 deletions
|
|
@ -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)
|
||||
})
|
||||
})
|
||||
|
|
|
|||
|
|
@ -54,7 +54,69 @@ This is extremely useful when you find a common utility pattern in your HTML tha
|
|||
}
|
||||
```
|
||||
|
||||
Note that `@@apply` **will not work** for mixing in hover or responsive variants of another utility. Instead, mix in the plain version of that utility into the `:hover` pseudo-selector or a new media query:
|
||||
Rules can listed on a single line or with multiple calls to `@@apply`:
|
||||
|
||||
```less
|
||||
.btn {
|
||||
@@apply .font-bold;
|
||||
@@apply .py-2;
|
||||
@@apply .px-4;
|
||||
@@apply .rounded;
|
||||
}
|
||||
```
|
||||
|
||||
You can mix `@@apply` declarations with normal CSS declarations too of course:
|
||||
|
||||
```less
|
||||
.btn:hover {
|
||||
@@apply .bg-blue-dark;
|
||||
transform: translateY(-1px);
|
||||
}
|
||||
```
|
||||
|
||||
Any rules mixed in with `@@apply` will have `!important` **removed** by default to avoid specificity issues:
|
||||
|
||||
```less
|
||||
// Input
|
||||
.foo {
|
||||
@@apply .bar;
|
||||
}
|
||||
|
||||
.bar {
|
||||
color: blue !important;
|
||||
}
|
||||
|
||||
// Output
|
||||
.foo {
|
||||
color: blue;
|
||||
}
|
||||
|
||||
.bar {
|
||||
color: blue !important;
|
||||
}
|
||||
```
|
||||
|
||||
If you'd like to `@@apply` an existing class and make it `!important`, simply add `!important` to the end of the declaration:
|
||||
|
||||
|
||||
```less
|
||||
// Input
|
||||
.btn {
|
||||
@@apply .font-bold .py-2 .px-4 .rounded !important;
|
||||
}
|
||||
|
||||
// Output
|
||||
.btn {
|
||||
font-weight: 700 !important;
|
||||
padding-top: .5rem !important;
|
||||
padding-bottom: .5rem !important;
|
||||
padding-right: 1rem !important;
|
||||
padding-left: 1rem !important;
|
||||
border-radius: .25rem !important;
|
||||
}
|
||||
```
|
||||
|
||||
Note that `@@apply` **will not work** for mixing in hover, focus, or responsive variants of another utility. Instead, mix in the plain version of that utility into the appropriate pseudo-selector or a new media query:
|
||||
|
||||
```less
|
||||
// Won't work:
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue