diff --git a/lib/core/index.js b/lib/core/index.js index 1502a2b..c2322ea 100755 --- a/lib/core/index.js +++ b/lib/core/index.js @@ -9,7 +9,7 @@ import gonzales from './gonzales'; import type { JsNode, gASTNode } from '../types'; import { - getRegularClassesMap, + getRegularClassesAndIdsMap, getComposesClassesMap, getExtendClassesMap, getParentSelectorClassesMap, @@ -150,13 +150,13 @@ export const getStyleClasses = (ast: gASTNode): ?Object => { */ eliminateGlobals(ast); - const classesMap = getRegularClassesMap(ast); + const classesAndIdsMap = getRegularClassesAndIdsMap(ast); const composedClassesMap = getComposesClassesMap(ast); const extendClassesMap = getExtendClassesMap(ast); const parentSelectorClassesMap = getParentSelectorClassesMap(ast); return { - ...classesMap, + ...classesAndIdsMap, ...composedClassesMap, ...extendClassesMap, ...parentSelectorClassesMap diff --git a/lib/core/traversalUtils.js b/lib/core/traversalUtils.js index d3a657f..b97564c 100644 --- a/lib/core/traversalUtils.js +++ b/lib/core/traversalUtils.js @@ -39,7 +39,7 @@ export const getICSSExportPropsMap = (ast: gASTNode): classMapType => { )(ruleSets); }; -export const getRegularClassesMap = (ast: gASTNode): classMapType => { +export const getRegularClassesAndIdsMap = (ast: gASTNode): classMapType => { const ruleSets: Array = []; ast.traverseByType('ruleset', node => ruleSets.push(node)); @@ -51,7 +51,7 @@ export const getRegularClassesMap = (ast: gASTNode): classMapType => { fp.map('content'), fp.filter({ type: 'ident' }), fp.flatMap('content'), - fp.filter({ type: 'class' }), + fp.filter(node => node.is('class') || node.is('id')), fp.flatMap('content'), fp.filter({ type: 'selector' }), fp.flatMap('content'), diff --git a/test/files/id.scss b/test/files/id.scss new file mode 100644 index 0000000..80b78d8 --- /dev/null +++ b/test/files/id.scss @@ -0,0 +1,3 @@ +#scopedId { + color: red; +} \ No newline at end of file diff --git a/test/lib/rules/no-undef-class.js b/test/lib/rules/no-undef-class.js index ae455f1..1ae838b 100644 --- a/test/lib/rules/no-undef-class.js +++ b/test/lib/rules/no-undef-class.js @@ -355,6 +355,19 @@ ruleTester.run('no-undef-class', rule, { `, options: [{ camelCase: 'dashes-only' }], }), + + /* + support id selectors + */ + test({ + code: ` + import s from './id.scss'; + + export default Foo = () => ( +
+ ); + `, + }), ], /* invalid cases @@ -656,5 +669,20 @@ ruleTester.run('no-undef-class', rule, { 'Class or exported property \'foo-baz\' not found', ], }), + /* + support id selectors + */ + test({ + code: ` + import s from './id.scss'; + + export default Foo = () => ( +
+ ); + `, + errors: [ + 'Class or exported property \'badScopedId\' not found', + ], + }), ], }); diff --git a/test/lib/rules/no-unused-class.js b/test/lib/rules/no-unused-class.js index d5c4bd8..f3f8074 100644 --- a/test/lib/rules/no-unused-class.js +++ b/test/lib/rules/no-unused-class.js @@ -222,6 +222,18 @@ ruleTester.run('no-unused-class', rule, { `, options: [{ camelCase: 'dashes-only' }], }), + /* + support id selectors + */ + test({ + code: ` + import s from './id.scss'; + + export default Foo = () => ( +
+ ); + `, + }), ], /* invalid cases @@ -419,5 +431,20 @@ ruleTester.run('no-unused-class', rule, { 'Unused classes found in noUnusedClass3.scss: foo-bar, alreadyCamelCased, snake_cased', ], }), + /* + support id selectors + */ + test({ + code: ` + import s from './id.scss'; + + export default Foo = () => ( +
Not using s.scopedId
+ ); + `, + errors: [ + 'Unused classes found in id.scss: scopedId', + ], + }), ], });