From ee4b418357bab934a2240d015c825ca68daffe2c Mon Sep 17 00:00:00 2001 From: Adam Wathan Date: Tue, 16 Mar 2021 13:31:43 -0400 Subject: [PATCH] WIP Not exactly the expected behavior yet. --- src/lib/expandApplyAtRules.js | 37 ++++++++++++++++++++--------------- tests/10-apply.test.css | 26 ++++++++++++++++++++++++ tests/10-apply.test.html | 2 ++ tests/10-apply.test.js | 11 +++++++++++ 4 files changed, 60 insertions(+), 16 deletions(-) diff --git a/src/lib/expandApplyAtRules.js b/src/lib/expandApplyAtRules.js index acf65de..d33dde6 100644 --- a/src/lib/expandApplyAtRules.js +++ b/src/lib/expandApplyAtRules.js @@ -43,18 +43,24 @@ function expandApplyAtRules(context) { let applyCandidates = new Set() // Collect all @apply rules and candidates - let applies = [] + let ruleApplies = new Map() root.walkAtRules('apply', (rule) => { let [candidates, important] = extractApplyCandidates(rule.params) + if (!ruleApplies.has(rule.parent)) { + ruleApplies.set(rule.parent, new Set()) + } + + let applies = ruleApplies.get(rule.parent) for (let util of candidates) { + applies.add([util, important]) applyCandidates.add(util) } - applies.push(rule) + rule.remove() }) // Start the @apply process if we have rules with @apply in them - if (applies.length > 0) { + if (ruleApplies.size > 0) { // Fill up some caches! let applyClassCache = buildApplyCache(applyCandidates, context) @@ -96,11 +102,9 @@ function expandApplyAtRules(context) { .join(', ') } - for (let apply of applies) { + for (let [applyParentRule, applyCandidates] of ruleApplies.entries()) { let siblings = [] - let [applyCandidates, important] = extractApplyCandidates(apply.params) - - for (let applyCandidate of applyCandidates) { + for (let [applyCandidate, important] of applyCandidates) { if (!applyClassCache.has(applyCandidate)) { throw apply.error( `The \`${applyCandidate}\` class does not exist. If \`${applyCandidate}\` is a custom class, make sure it is defined within a \`@layer\` directive.` @@ -113,7 +117,11 @@ function expandApplyAtRules(context) { let root = postcss.root({ nodes: [node.clone()] }) root.walkRules((rule) => { - rule.selector = replaceSelector(apply.parent.selector, rule.selector, applyCandidate) + rule.selector = replaceSelector( + applyParentRule.selector, + rule.selector, + applyCandidate + ) rule.walkDecls((d) => { d.important = important }) @@ -125,16 +133,13 @@ function expandApplyAtRules(context) { // Inject the rules, sorted, correctly for (let [, sibling] of siblings.sort(([a], [z]) => bigSign(z.sort - a.sort))) { - // `apply.parent` is referring to the node at `.abc` in: .abc { @apply mt-2 } - apply.parent.after(sibling) + // `applyParentRule` is referring to the node at `.abc` in: .abc { @apply mt-2 } + applyParentRule.after(sibling) } - // If there are left-over declarations, just remove the @apply - if (apply.parent.nodes.length > 1) { - apply.remove() - } else { - // The node is empty, drop the full node - apply.parent.remove() + // The node is empty, drop the full node + if (applyParentRule.nodes.length === 0) { + applyParentRule.remove() } } } diff --git a/tests/10-apply.test.css b/tests/10-apply.test.css index ceca6f3..ba54b10 100644 --- a/tests/10-apply.test.css +++ b/tests/10-apply.test.css @@ -178,3 +178,29 @@ font-weight: 400; } } +.multiple-apply-directives { + text-align: center; + font-weight: 600; +} +.multiple-apply-directives:hover { + font-weight: 700; +} +.multiple-apply-directives:focus { + font-weight: 500; +} +@media (min-width: 1024px) { + .multiple-apply-directives { + font-weight: 300; + } +} +@media (min-width: 1280px) { + .multiple-apply-directives:focus { + font-weight: 900; + } +} +.apply-sandwich { + font-weight: 300; + text-align: right; + font-weight: 500; + text-align: center; +} diff --git a/tests/10-apply.test.html b/tests/10-apply.test.html index 7f9c472..48cb5b6 100644 --- a/tests/10-apply.test.html +++ b/tests/10-apply.test.html @@ -23,5 +23,7 @@
+
+
diff --git a/tests/10-apply.test.js b/tests/10-apply.test.js index 173f190..3ba6f08 100644 --- a/tests/10-apply.test.js +++ b/tests/10-apply.test.js @@ -65,6 +65,16 @@ test('@apply', () => { @apply font-bold hover:font-normal; } } + .multiple-apply-directives { + @apply xl:focus:font-black hover:font-bold; + @apply lg:font-light focus:font-medium; + @apply font-semibold text-center; + } + .apply-sandwich { + @apply p-4; + padding-top: 11px; + @apply py-3; + } } @layer utilities { @@ -82,4 +92,5 @@ test('@apply', () => { }) }) +// TODO: Test @apply !important // TODO: Test stuff that should throw