diff --git a/README.md b/README.md index 7eeb67f..bf94433 100644 --- a/README.md +++ b/README.md @@ -200,6 +200,7 @@ Each item has emojis denoting: | [crisp/vue-no-regex-data](https://github.com/crisp-oss/eslint-plugin-crisp/blob/master/rules/vue-no-regex-data.js) | Disallows regular expressions to be declared in Vue data object | | 🟢 | | [crisp/vue-props-declaration-multiline](https://github.com/crisp-oss/eslint-plugin-crisp/blob/master/rules/vue-props-declaration-multiline.js) | Enforces props declarations to be multiline | | 🟢 | | [crisp/vue-props-declaration-order](https://github.com/crisp-oss/eslint-plugin-crisp/blob/master/rules/vue-props-declaration-order.js) | Ensures props declarations are alphabetically ordered | | 🟢 | +| [crisp/vue-ref-case](https://github.com/crisp-oss/eslint-plugin-crisp/blob/master/rules/vue-ref-case.js) | Enforces `ref` attributes to snake case | | 🟢 | ## License diff --git a/index.js b/index.js index bf0af89..1b87030 100644 --- a/index.js +++ b/index.js @@ -41,7 +41,8 @@ module.exports = { "vue-html-indent": require("./rules/vue-html-indent"), "vue-html-quotes": require("./rules/vue-html-quotes"), "vue-no-regex-data": require("./rules/vue-no-regex-data"), + "vue-props-declaration-multiline": require("./rules/vue-props-declaration-multiline"), "vue-props-declaration-order": require("./rules/vue-props-declaration-order"), - "vue-props-declaration-multiline": require("./rules/vue-props-declaration-multiline") + "vue-ref-case": require("./rules/vue-ref-case") } }; diff --git a/package-lock.json b/package-lock.json index 5aa2901..3d62574 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "eslint-plugin-crisp", - "version": "1.0.88", + "version": "1.0.89", "lockfileVersion": 3, "requires": true, "packages": { diff --git a/package.json b/package.json index 4387dbf..8d9fc9c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "eslint-plugin-crisp", - "version": "1.0.88", + "version": "1.0.89", "description": "Custom ESLint Rules for Crisp", "author": "Crisp IM SAS", "main": "index.js", diff --git a/recommended-vue.js b/recommended-vue.js index 717c6dc..9f41628 100644 --- a/recommended-vue.js +++ b/recommended-vue.js @@ -342,6 +342,7 @@ module.exports = { "crisp/vue-html-quotes": "error", "crisp/vue-no-regex-data": "error", "crisp/vue-props-declaration-multiline": "error", - "crisp/vue-props-declaration-order": "error" + "crisp/vue-props-declaration-order": "error", + "crisp/vue-ref-case": "error" } } diff --git a/rules/vue-ref-case.js b/rules/vue-ref-case.js new file mode 100644 index 0000000..1c510b5 --- /dev/null +++ b/rules/vue-ref-case.js @@ -0,0 +1,29 @@ +module.exports = { + meta: { + type: "layout", + docs: { + description: "enforce ref attributes to be snake-cased", + category: "Stylistic Issues", + recommended: false, + }, + fixable: null + }, + + create(context) { + return context.parserServices.defineTemplateBodyVisitor({ + "VAttribute[directive=false][key.name='ref']"(node) { + const refValue = node.value && node.value.value; + + if (refValue && !/^[a-z]+(_[a-z]+)*$/.test(refValue)) { + context.report({ + node, + message: "Ref attribute \"{{refValue}}\" should be snake-cased.", + data: { + refValue, + }, + }); + } + } + }) + } +}; \ No newline at end of file