Skip to content

Commit 12dd81b

Browse files
committed
Working on @variants at-rule
Currently supports focus and hover, need to add responsive which will be a whole horrible can of worms.
1 parent 0dbc220 commit 12dd81b

File tree

2 files changed

+112
-0
lines changed

2 files changed

+112
-0
lines changed

__tests__/variantsAtRule.test.js

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
import postcss from 'postcss'
2+
import plugin from '../src/lib/substituteVariantsAtRules'
3+
4+
function run(input, opts = () => {}) {
5+
return postcss([plugin(opts)]).process(input)
6+
}
7+
8+
test('it can generate hover variants', () => {
9+
const input = `
10+
@variants hover {
11+
.banana { color: yellow; }
12+
.chocolate { color: brown; }
13+
}
14+
`
15+
16+
const output = `
17+
.banana { color: yellow; }
18+
.chocolate { color: brown; }
19+
.hover\\:banana:hover { color: yellow; }
20+
.hover\\:chocolate:hover { color: brown; }
21+
`
22+
23+
return run(input).then(result => {
24+
expect(result.css).toMatchCss(output)
25+
expect(result.warnings().length).toBe(0)
26+
})
27+
})
28+
29+
test('it can generate focus variants', () => {
30+
const input = `
31+
@variants focus {
32+
.banana { color: yellow; }
33+
.chocolate { color: brown; }
34+
}
35+
`
36+
37+
const output = `
38+
.banana { color: yellow; }
39+
.chocolate { color: brown; }
40+
.focus\\:banana:focus { color: yellow; }
41+
.focus\\:chocolate:focus { color: brown; }
42+
`
43+
44+
return run(input).then(result => {
45+
expect(result.css).toMatchCss(output)
46+
expect(result.warnings().length).toBe(0)
47+
})
48+
})
49+
50+
test('it can generate hover and focus variants', () => {
51+
const input = `
52+
@variants hover, focus {
53+
.banana { color: yellow; }
54+
.chocolate { color: brown; }
55+
}
56+
`
57+
58+
const output = `
59+
.banana { color: yellow; }
60+
.chocolate { color: brown; }
61+
.focus\\:banana:focus { color: yellow; }
62+
.focus\\:chocolate:focus { color: brown; }
63+
.hover\\:banana:hover { color: yellow; }
64+
.hover\\:chocolate:hover { color: brown; }
65+
`
66+
67+
return run(input).then(result => {
68+
expect(result.css).toMatchCss(output)
69+
expect(result.warnings().length).toBe(0)
70+
})
71+
})
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
import _ from 'lodash'
2+
import postcss from 'postcss'
3+
4+
const variantGenerators = {
5+
hover: (rule) => {
6+
const clonedRule = rule.clone()
7+
8+
clonedRule.walkRules(rule => {
9+
rule.selector = `.hover\\:${rule.selector.slice(1)}:hover`
10+
})
11+
12+
return clonedRule.nodes
13+
},
14+
focus: (rule) => {
15+
const clonedRule = rule.clone()
16+
17+
clonedRule.walkRules(rule => {
18+
rule.selector = `.focus\\:${rule.selector.slice(1)}:focus`
19+
})
20+
21+
return clonedRule.nodes
22+
},
23+
}
24+
25+
export default function() {
26+
return function(css) {
27+
css.walkAtRules('variants', atRule => {
28+
const variants = postcss.list.comma(atRule.params)
29+
30+
atRule.before(atRule.clone().nodes)
31+
32+
_.forEach(['focus', 'hover'], (variant) => {
33+
if (variants.includes(variant)) {
34+
atRule.before(variantGenerators[variant](atRule))
35+
}
36+
})
37+
38+
atRule.remove()
39+
})
40+
}
41+
}

0 commit comments

Comments
 (0)