diff --git a/extensions/style-helper/CHANGELOG.md b/extensions/style-helper/CHANGELOG.md index c88753b58..bd857e991 100644 --- a/extensions/style-helper/CHANGELOG.md +++ b/extensions/style-helper/CHANGELOG.md @@ -2,6 +2,7 @@ ## 1.1.1 - feat: add `className={styles.xxx}` automatic completion will be provided when editing css file +- fix: `style={styles.xxx}` automatic completion failed with nested css file ## 1.1.0 - feat: add `className={}` completion item diff --git a/extensions/style-helper/src/styleInfoViewer/findStyleSelectors.ts b/extensions/style-helper/src/styleInfoViewer/findStyleSelectors.ts index 81573b7a6..9cc9f5058 100644 --- a/extensions/style-helper/src/styleInfoViewer/findStyleSelectors.ts +++ b/extensions/style-helper/src/styleInfoViewer/findStyleSelectors.ts @@ -1,6 +1,7 @@ import * as fs from 'fs'; import * as path from 'path'; -import css from 'css'; +import * as css from 'css'; +import flatten from 'css-flatten'; import { IStyle } from './findStyle'; import { IStyleDependency } from './findStyleDependencies'; @@ -10,12 +11,44 @@ export default function findStyleSelectors(directory: string, styleDependencies: for (let i = 0, l = styleDependencies.length; i < l; i++) { const file = path.join(directory, styleDependencies[i].source); - const { stylesheet } = css.parse(fs.readFileSync(file, 'utf-8')); + + const fileContent = fs.readFileSync(file, 'utf-8'); + let cssContent = fileContent; + + // Remove media and keyframes, it will cause css.parse error + cssContent = cssContent.replace(/@[media|keyframes][^{]+\{([\s\S]+?})\s*}/g, ''); + + if ( + // Flattens nested SASS LESS string + /s(c|a)ss$|\.less$/.test(file) + ) { + // https://www.npmjs.com/package/css-flatten + // Before: + // .foo { + // color: red; + // .bar { + // color: blue; + // } + // } + // After: + // .foo { + // color: red; + // } + // .foo .bar { + // color: blue; + // } + cssContent = flatten(cssContent); + } + + const { stylesheet } = css.parse(cssContent); // eslint-disable-next-line stylesheet.rules.forEach((rule: IStyle) => { if (rule.selectors) { - selectors = selectors.concat(rule.selectors); + selectors = selectors.concat(rule.selectors.map((selector) => { + // .foo .bar => .bar + return selector.split(' ').pop() || ''; + })); } }); }