Skip to content
This repository was archived by the owner on Apr 6, 2021. It is now read-only.

Commit eae1d13

Browse files
committed
Add basic experimental support for !font-bold-style important modifiers
1 parent fe18ede commit eae1d13

File tree

4 files changed

+125
-2
lines changed

4 files changed

+125
-2
lines changed

src/lib/generateRules.js

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ const parseObjectStyles = require('tailwindcss/lib/util/parseObjectStyles').defa
33
const { isPlainObject, bigSign } = require('./utils')
44
const selectorParser = require('postcss-selector-parser')
55
const prefixSelector = require('tailwindcss/lib/util/prefixSelector').default
6+
const { updateAllClasses } = require('../pluginUtils')
67

78
let classNameParser = selectorParser((selectors) => {
89
return selectors.first.filter(({ type }) => type === 'class').pop().value
@@ -64,6 +65,27 @@ function applyPrefix(matches, context) {
6465
return matches
6566
}
6667

68+
function applyImportant(matches) {
69+
if (matches.length === 0) {
70+
return matches
71+
}
72+
let result = []
73+
74+
for (let [{ sort, layer, options }, rule] of matches) {
75+
let container = postcss.root({ nodes: [rule] })
76+
container.walkRules((r) => {
77+
r.selector = updateAllClasses(r.selector, (className) => {
78+
return `!${className}`
79+
})
80+
r.walkDecls((d) => (d.important = true))
81+
})
82+
let withOffset = [{ sort: sort, layer, options }, container.nodes[0]]
83+
result.push(withOffset)
84+
}
85+
86+
return result
87+
}
88+
6789
// Takes a list of rule tuples and applies a variant like `hover`, sm`,
6890
// whatever to it. We used to do some extra caching here to avoid generating
6991
// a variant of the same rule more than once, but this was never hit because
@@ -155,8 +177,9 @@ function* resolveMatchedPlugins(classCandidate, context) {
155177
let candidatePrefix = classCandidate
156178
let negative = false
157179

158-
const twConfigPrefix = context.tailwindConfig.prefix || ''
159-
const twConfigPrefixLen = twConfigPrefix.length
180+
let twConfigPrefix = context.tailwindConfig.prefix || ''
181+
let twConfigPrefixLen = twConfigPrefix.length
182+
160183
if (candidatePrefix[twConfigPrefixLen] === '-') {
161184
negative = true
162185
candidatePrefix = twConfigPrefix + candidatePrefix.slice(twConfigPrefixLen + 1)
@@ -179,6 +202,12 @@ function sortAgainst(toSort, against) {
179202
function* resolveMatches(candidate, context) {
180203
let separator = context.tailwindConfig.separator
181204
let [classCandidate, ...variants] = candidate.split(separator).reverse()
205+
let important = false
206+
207+
if (classCandidate.startsWith('!')) {
208+
important = true
209+
classCandidate = classCandidate.slice(1)
210+
}
182211

183212
// Strip prefix
184213
// md:hover:tw-bg-black
@@ -220,6 +249,10 @@ function* resolveMatches(candidate, context) {
220249

221250
matches = applyPrefix(matches, context)
222251

252+
if (important) {
253+
matches = applyImportant(matches, context)
254+
}
255+
223256
for (let variant of variants) {
224257
matches = applyVariant(variant, matches, context)
225258
}

tests/14-important-modifier.test.css

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
* {
2+
--tw-shadow: 0 0 #0000;
3+
--tw-ring-inset: var(--tw-empty, /*!*/ /*!*/);
4+
--tw-ring-offset-width: 0px;
5+
--tw-ring-offset-color: #fff;
6+
--tw-ring-color: rgba(59, 130, 246, 0.5);
7+
--tw-ring-offset-shadow: 0 0 #0000;
8+
--tw-ring-shadow: 0 0 #0000;
9+
}
10+
.\!container {
11+
width: 100% !important;
12+
}
13+
@media (min-width: 640px) {
14+
.\!container {
15+
max-width: 640px !important;
16+
}
17+
}
18+
@media (min-width: 768px) {
19+
.\!container {
20+
max-width: 768px !important;
21+
}
22+
}
23+
@media (min-width: 1024px) {
24+
.\!container {
25+
max-width: 1024px !important;
26+
}
27+
}
28+
@media (min-width: 1280px) {
29+
.\!container {
30+
max-width: 1280px !important;
31+
}
32+
}
33+
@media (min-width: 1536px) {
34+
.\!container {
35+
max-width: 1536px !important;
36+
}
37+
}
38+
.\!font-bold {
39+
font-weight: 700 !important;
40+
}
41+
.hover\:\!text-center:hover {
42+
text-align: center !important;
43+
}
44+
@media (min-width: 1024px) {
45+
.lg\:\!opacity-50 {
46+
opacity: 0.5 !important;
47+
}
48+
}
49+
@media (min-width: 1280px) {
50+
.xl\:focus\:disabled\:\!float-right:focus:disabled {
51+
float: right !important;
52+
}
53+
}

tests/14-important-modifier.test.html

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
<div class="!container"></div>
2+
<div class="!font-bold"></div>
3+
<div class="hover:!text-center"></div>
4+
<div class="lg:!opacity-50"></div>
5+
<div class="xl:focus:disabled:!float-right"></div>

tests/14-important-modifier.test.js

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
const postcss = require('postcss')
2+
const tailwind = require('../src/index.js')
3+
const fs = require('fs')
4+
const path = require('path')
5+
6+
function run(input, config = {}) {
7+
return postcss([tailwind(config)]).process(input, { from: path.resolve(__filename) })
8+
}
9+
10+
test('important boolean', () => {
11+
let config = {
12+
important: false,
13+
darkMode: 'class',
14+
purge: [path.resolve(__dirname, './14-important-modifier.test.html')],
15+
corePlugins: { preflight: false },
16+
theme: {},
17+
plugins: [],
18+
}
19+
20+
let css = `
21+
@tailwind base;
22+
@tailwind components;
23+
@tailwind utilities;
24+
`
25+
26+
return run(css, config).then((result) => {
27+
let expectedPath = path.resolve(__dirname, './14-important-modifier.test.css')
28+
let expected = fs.readFileSync(expectedPath, 'utf8')
29+
30+
expect(result.css).toMatchCss(expected)
31+
})
32+
})

0 commit comments

Comments
 (0)