Repository: vuejs/eslint-plugin-vue (js)

Issue:
no-unused-properties: Misses v-bind inside "style" section (with repro)
**Checklist**

- [+] I have tried restarting my IDE and the issue persists.
- [+] I have read the [FAQ](https://eslint.vuejs.org/user-guide/#faq) and my problem is not listed.

**Tell us about your environment**

- **ESLint version:** ^6.7.2
- **eslint-plugin-vue version:** ^7.0.0
- **Node version:** 14.18
- **Operating System:** Windows 10

**Please show your full configuration:**

See:
https://github.com/ilyub/repro-vue-no-unused-properties/blob/master/.eslintrc.js

```json5
rules: {
    "vue/no-unused-components": "warn",
    "vue/no-unused-properties": "warn",
  },
```

**What did you do?**	

See:
https://github.com/ilyub/repro-vue-no-unused-properties/blob/master/src/components/HelloWorld.vue

```vue
<template>
...
</template>

<script lang="ts">
export default defineComponent({
  name: "HelloWorld",
  props: {
    msg: String,
    background: String,
    otherProp: String,
  },
});
</script>

<style scoped lang="scss">
h3 {
  background: v-bind(background);
}
</style>
```

**What did you expect to happen?**

One error: from otherProp.

**What actually happened?**

Two errors: from otherProp and background.

Note that background is used in "style" section.

IMPORTANT NOTE:
Bug occurs in the presense of "vue/no-unused-components".
If you disable it then you get one error as expected.

**Repository to reproduce this issue**

https://github.com/ilyub/repro-vue-no-unused-properties

Pull request description:
Fix false positives due to conflicts with other rules in `vue/no-unused-properties` rule


fixes #1789

Patch:
diff --git a/lib/rules/no-unused-properties.js b/lib/rules/no-unused-properties.js
index 74762e44..1414df35 100644
--- a/lib/rules/no-unused-properties.js
+++ b/lib/rules/no-unused-properties.js
@@ -586,8 +586,7 @@ module.exports = {
         }
       }),
       {
-        /** @param {Program} node */
-        'Program:exit'(node) {
+        Program() {
           const styleVars = getStyleVariablesContext(context)
           if (styleVars) {
             templatePropertiesContainer.propertyReferences.push(
@@ -596,6 +595,9 @@ module.exports = {
               )
             )
           }
+        },
+        /** @param {Program} node */
+        'Program:exit'(node) {
           if (!node.templateBody) {
             reportUnusedProperties()
           }


Test patch:
diff --git a/tests/lib/rules/no-unused-properties.js b/tests/lib/rules/no-unused-properties.js
index 0023443c..a75d83e7 100644
--- a/tests/lib/rules/no-unused-properties.js
+++ b/tests/lib/rules/no-unused-properties.js
@@ -4,7 +4,8 @@
  */
 'use strict'
 
-const RuleTester = require('eslint').RuleTester
+const { RuleTester, Linter } = require('eslint')
+const assert = require('assert')
 const rule = require('../../../lib/rules/no-unused-properties')
 
 const tester = new RuleTester({
@@ -2805,3 +2806,42 @@ tester.run('no-unused-properties', rule, {
     }
   ]
 })
+
+// https://github.com/vuejs/eslint-plugin-vue/issues/1789
+describe('`vue/no-unused-properties` and `vue/no-unused-components` should not conflict.', () => {
+  const linter = new Linter()
+  linter.defineParser('vue-eslint-parser', require('vue-eslint-parser'))
+  linter.defineRule(
+    'vue/no-unused-components',
+    require('../../../lib/rules/no-unused-components')
+  )
+  linter.defineRule('vue/no-unused-properties', rule)
+
+  const config = {
+    parser: 'vue-eslint-parser',
+    parserOptions: {
+      ecmaVersion: 2020,
+      sourceType: 'module'
+    },
+    rules: {
+      'vue/no-unused-components': 'error',
+      'vue/no-unused-properties': 'error'
+    }
+  }
+
+  it('should not be a false positive when using CSS v-bind().', () => {
+    const code = `
+      <template></template>
+      <script>
+        export default {
+          props: ['a']
+        };
+      </script>
+      <style>
+      a {
+        color: v-bind(a);
+      }
+      </style>`
+    assert.deepStrictEqual(linter.verify(code, config, 'test.vue'), [])
+  })
+})