Skip to content

Commit

Permalink
fix: mixin of class from st-scope params (#2853)
Browse files Browse the repository at this point in the history
* fix: mixin of class from st-scope params

* test: add multi selector test
  • Loading branch information
idoros authored Apr 22, 2023
1 parent 31f8143 commit 03f368f
Show file tree
Hide file tree
Showing 2 changed files with 70 additions and 10 deletions.
36 changes: 26 additions & 10 deletions packages/core/src/helpers/rule.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,23 +40,19 @@ export function createSubsetAst<T extends postcss.Root | postcss.AtRule>(
mixinTarget?: T,
isRoot = false,
getCustomSelector?: (name: string) => SelectorList | undefined,
scopeSelector = ''
isNestedInMixin = false
): T {
// keyframes on class mixin?
const prefixSelectorList = parseSelectorWithCache(selectorPrefix);
const prefixType = prefixSelectorList[0].nodes[0];
const containsPrefix = containsMatchInFirstChunk.bind(null, prefixType);
const mixinRoot = mixinTarget ? mixinTarget : postcss.root();
const scopeSelectorAST = parseSelectorWithCache(scopeSelector);
root.nodes.forEach((node) => {
if (node.type === `rule` && (node.selector === ':vars' || node.selector === ':import')) {
// nodes that don't mix
return;
} else if (node.type === `rule`) {
let selectorAst = parseSelectorWithCache(node.selector, { clone: true });
if (scopeSelector) {
selectorAst = scopeNestedSelector(scopeSelectorAST, selectorAst, isRoot).ast;
}
const selectorAst = parseSelectorWithCache(node.selector, { clone: true });
let ast = isRoot
? scopeNestedSelector(prefixSelectorList, selectorAst, true).ast
: selectorAst;
Expand All @@ -65,7 +61,8 @@ export function createSubsetAst<T extends postcss.Root | postcss.AtRule>(
/*don't report*/
});
}
const matchesSelectors = isRoot ? ast : ast.filter((node) => containsPrefix(node));
const matchesSelectors =
isRoot || isNestedInMixin ? ast : ast.filter((node) => containsPrefix(node));

if (matchesSelectors.length) {
const selector = stringifySelector(
Expand All @@ -88,17 +85,36 @@ export function createSubsetAst<T extends postcss.Root | postcss.AtRule>(
node.name === 'layer' ||
node.name === 'container'
) {
const scopeSelector = node.name === 'st-scope' ? node.params : '';
let scopeSelector = node.name === 'st-scope' ? node.params : '';
let isNestedInMixin = false;
if (scopeSelector) {
const ast = parseSelectorWithCache(scopeSelector, { clone: true });
const matchesSelectors = isRoot
? ast
: ast.filter((node) => containsPrefix(node));
if (matchesSelectors.length) {
isNestedInMixin = true;
scopeSelector = stringifySelector(
matchesSelectors.map((selectorNode) => {
if (!isRoot) {
selectorNode = fixChunkOrdering(selectorNode, prefixType);
}
replaceTargetWithNesting(selectorNode, prefixType);
return selectorNode;
})
);
}
}
const atRuleSubset = createSubsetAst(
node,
selectorPrefix,
postcss.atRule({
params: node.params,
params: scopeSelector || node.params,
name: node.name,
}),
isRoot,
getCustomSelector,
scopeSelector
isNestedInMixin
);
if (atRuleSubset.nodes) {
mixinRoot.append(atRuleSubset);
Expand Down
44 changes: 44 additions & 0 deletions packages/core/test/features/st-mixin.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1629,6 +1629,50 @@ describe(`features/st-mixin`, () => {
shouldReportNoDiagnostics(meta);
});
});
describe('st-scope', () => {
it('should collect mixin from st-sope selector', () => {
const { sheets } = testStylableCore({
'/mix.st.css': `
@st-scope .mix {
.part { color: green; }
.part2 { color: purple; }
&:state { color: gold; }
}
@st-scope .mix.compoundAfter {
.part { color: blue; }
}
@st-scope .compoundBefore.mix {
.part { color: pink; }
}
@st-scope .mix, .notMix, .mix[extra] {
.part { color: white; }
}
.mix {
-st-states: state;
}
`,
'/entry.st.css': `
@st-import [mix] from './mix.st.css';
/*
@rule(descendant)[1] .entry__into .mix__part {color: green;}
@rule(descendant2)[2] .entry__into .mix__part2 {color: purple;}
@rule(state)[3] .entry__into.mix--state {color: gold;}
@rule(+after)[4] .entry__into.mix__compoundAfter .mix__part {color: blue;}
@rule(+before)[5] .entry__into.mix__compoundBefore .mix__part {color: pink;}
@rule(multi selector)[6] .entry__into .mix__part, .entry__into[extra] .mix__part {color: white;}
*/
.into {
-st-mixin: mix;
}
`,
});

const { meta } = sheets['/entry.st.css'];

shouldReportNoDiagnostics(meta);
});
});
describe(`higher-level feature integrations`, () => {
// ToDo: move to their higher level feature spec when created
describe(`css-asset`, () => {
Expand Down

0 comments on commit 03f368f

Please sign in to comment.