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

Commit d55078d

Browse files
Fix multiple @apply involving responsive rules (#151)
* Fix multiple @apply of responsive rules We achieve this by: 1. handling applies on a per-parent basis 2. Splitting @apply a b c into @apply a; @apply b; @apply c; (in that order) and then sorting all applies in a given node * Use destructing when looping over candidates Co-authored-by: Robin Malfait <malfait.robin@gmail.com> Co-authored-by: Robin Malfait <malfait.robin@gmail.com>
1 parent 602e6b0 commit d55078d

File tree

3 files changed

+65
-6
lines changed

3 files changed

+65
-6
lines changed

src/lib/expandApplyAtRules.js

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -102,8 +102,15 @@ function expandApplyAtRules(context) {
102102
.join(', ')
103103
}
104104

105+
/** @type {Map<import('postcss').Node, [string, boolean, import('postcss').Node[]][]>} */
106+
let perParentApplies = new Map()
107+
108+
// Collect all apply candidates and their rules
105109
for (let apply of applies) {
106-
let siblings = []
110+
let candidates = perParentApplies.get(apply.parent) || []
111+
112+
perParentApplies.set(apply.parent, candidates)
113+
107114
let [applyCandidates, important] = extractApplyCandidates(apply.params)
108115

109116
for (let applyCandidate of applyCandidates) {
@@ -115,13 +122,22 @@ function expandApplyAtRules(context) {
115122

116123
let rules = applyClassCache.get(applyCandidate)
117124

125+
candidates.push([applyCandidate, important, rules])
126+
}
127+
}
128+
129+
for (const [parent, candidates] of perParentApplies) {
130+
let siblings = []
131+
132+
for (let [applyCandidate, important, rules] of candidates) {
118133
for (let [meta, node] of rules) {
119134
let root = postcss.root({ nodes: [node.clone()] })
120-
let canRewriteSelector = node.type !== 'atrule' || (node.type === 'atrule' && node.name !== 'keyframes');
135+
let canRewriteSelector =
136+
node.type !== 'atrule' || (node.type === 'atrule' && node.name !== 'keyframes')
121137

122138
if (canRewriteSelector) {
123139
root.walkRules((rule) => {
124-
rule.selector = replaceSelector(apply.parent.selector, rule.selector, applyCandidate)
140+
rule.selector = replaceSelector(parent.selector, rule.selector, applyCandidate)
125141

126142
rule.walkDecls((d) => {
127143
d.important = important
@@ -134,11 +150,13 @@ function expandApplyAtRules(context) {
134150
}
135151

136152
// Inject the rules, sorted, correctly
137-
const nodes = siblings.sort(([a], [z]) => bigSign(a.sort - z.sort)).map(s => s[1])
153+
const nodes = siblings.sort(([a], [z]) => bigSign(a.sort - z.sort)).map((s) => s[1])
138154

139-
// `apply.parent` is referring to the node at `.abc` in: .abc { @apply mt-2 }
140-
apply.parent.after(nodes)
155+
// `parent` refers to the node at `.abc` in: .abc { @apply mt-2 }
156+
parent.after(nodes)
157+
}
141158

159+
for (let apply of applies) {
142160
// If there are left-over declarations, just remove the @apply
143161
if (apply.parent.nodes.length > 1) {
144162
apply.remove()

tests/10-apply.test.css

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -265,6 +265,38 @@
265265
color: green;
266266
font-weight: 700;
267267
}
268+
h1 {
269+
font-size: 1.5rem;
270+
line-height: 2rem;
271+
}
272+
@media (min-width: 640px) {
273+
h1 {
274+
font-size: 1.875rem;
275+
line-height: 2.25rem;
276+
}
277+
}
278+
@media (min-width: 1024px) {
279+
h1 {
280+
font-size: 1.5rem;
281+
line-height: 2rem;
282+
}
283+
}
284+
h2 {
285+
font-size: 1.5rem;
286+
line-height: 2rem;
287+
}
288+
@media (min-width: 640px) {
289+
h2 {
290+
font-size: 1.5rem;
291+
line-height: 2rem;
292+
}
293+
}
294+
@media (min-width: 1024px) {
295+
h2 {
296+
font-size: 1.5rem;
297+
line-height: 2rem;
298+
}
299+
}
268300
@keyframes spin {
269301
to {
270302
transform: rotate(360deg);

tests/10-apply.test.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,15 @@ test('@apply', () => {
9999
.use-with-other-properties-component {
100100
@apply use-with-other-properties-base;
101101
}
102+
103+
h1 {
104+
@apply text-2xl lg:text-2xl sm:text-3xl;
105+
}
106+
h2 {
107+
@apply text-2xl;
108+
@apply lg:text-2xl;
109+
@apply sm:text-2xl;
110+
}
102111
}
103112
104113
@layer utilities {

0 commit comments

Comments
 (0)