Skip to content

Commit 1522029

Browse files
authored
Allow for recursively applying user defined classes (#2832)
1 parent 1e0fc09 commit 1522029

File tree

2 files changed

+33
-13
lines changed

2 files changed

+33
-13
lines changed

__tests__/applyAtRule.test.js

+14-7
Original file line numberDiff line numberDiff line change
@@ -593,7 +593,7 @@ test('you can apply classes recursively', () => {
593593
})
594594
})
595595

596-
test.skip('you can apply complex classes recursively', () => {
596+
test('you can apply complex classes recursively', () => {
597597
const input = `
598598
.button {
599599
@apply rounded-xl px-6 py-2 hover:text-white focus:border-opacity-100;
@@ -603,41 +603,48 @@ test.skip('you can apply complex classes recursively', () => {
603603
@apply button bg-yellow-600 text-gray-200;
604604
}
605605
`
606+
606607
const expected = `
607608
.button:focus {
608609
--tw-border-opacity: 1;
609610
}
611+
610612
.button {
611613
border-radius: 0.75rem;
612614
padding-top: 0.5rem;
613615
padding-bottom: 0.5rem;
614616
padding-left: 1.5rem;
615617
padding-right: 1.5rem;
616618
}
619+
617620
.button:hover {
618621
--tw-text-opacity: 1;
619622
color: rgba(255, 255, 255, var(--tw-text-opacity));
620623
}
624+
625+
.button-yellow {
626+
--tw-bg-opacity: 1;
627+
background-color: rgba(217, 119, 6, var(--tw-bg-opacity));
628+
--tw-text-opacity: 1;
629+
color: rgba(229, 231, 235, var(--tw-text-opacity));
630+
}
631+
621632
.button-yellow:focus {
622633
--tw-border-opacity: 1;
623634
}
635+
624636
.button-yellow {
625637
border-radius: 0.75rem;
626638
padding-top: 0.5rem;
627639
padding-bottom: 0.5rem;
628640
padding-left: 1.5rem;
629641
padding-right: 1.5rem;
630642
}
643+
631644
.button-yellow:hover {
632645
--tw-text-opacity: 1;
633646
color: rgba(255, 255, 255, var(--tw-text-opacity));
634647
}
635-
.button-yellow {
636-
--tw-bg-opacity: 1;
637-
background-color: rgba(217, 119, 6, var(--tw-bg-opacity));
638-
--tw-text-opacity: 1;
639-
color: rgba(229, 231, 235, var(--tw-text-opacity));
640-
}
641648
`
642649

643650
expect.assertions(2)

src/lib/substituteClassApplyAtRules.js

+19-6
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ function buildUtilityMap(css, lookupTree) {
9696
let index = 0
9797
const utilityMap = {}
9898

99-
function handle(rule) {
99+
function handle(getRule, rule) {
100100
const utilityNames = extractUtilityNames(rule.selector)
101101

102102
utilityNames.forEach((utilityName, i) => {
@@ -108,16 +108,29 @@ function buildUtilityMap(css, lookupTree) {
108108
index,
109109
utilityName,
110110
classPosition: i,
111-
get rule() {
112-
return cloneRuleWithParent(rule)
113-
},
111+
...getRule(rule),
114112
})
115113
index++
116114
})
117115
}
118116

119-
lookupTree.walkRules(handle)
120-
css.walkRules(handle)
117+
// Lookup tree is the big lookup tree, making the rule lazy allows us to save
118+
// some memory because we don't need everything.
119+
lookupTree.walkRules(
120+
handle.bind(null, (rule) => ({
121+
get rule() {
122+
return cloneRuleWithParent(rule)
123+
},
124+
}))
125+
)
126+
127+
// This is the end user's css. This might contain rules that we want to
128+
// apply. We want immediate copies of everything in case that we have user
129+
// defined classes that are recursively applied. Down below we are modifying
130+
// the rules directly. We could do a better solution where we keep track of a
131+
// dependency tree, but that is a bit more complex. Might revisit later,
132+
// we'll see how this turns out!
133+
css.walkRules(handle.bind(null, (rule) => ({ rule: cloneRuleWithParent(rule) })))
121134

122135
return utilityMap
123136
}

0 commit comments

Comments
 (0)