UNPKG

eslint-plugin-vuejs-accessibility

Version:
92 lines (91 loc) 3.21 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const utils_1 = require("../utils"); function isLabelElement(node, { labelComponents = [] }) { const allLabelComponents = labelComponents.concat("label"); return (0, utils_1.isMatchingElement)(node, allLabelComponents); } function hasNestedLabelElement(node, options) { const { parent } = node; if (isLabelElement(parent, options)) { return true; } return (parent && parent.type === "VElement" && hasNestedLabelElement(parent, options)); } /** * Check if the form control at least has an "id" to be associated with a label * Can't really check for the label with a matching "for" attribute, because * checking every element in the file may lead to bad performance. */ function hasIdForLabelElement(node) { const id = (0, utils_1.getElementAttributeValue)(node, "id"); return Boolean(id); } const rule = { meta: { type: "problem", docs: { url: (0, utils_1.makeDocsURL)("form-control-has-label") }, messages: { default: "Each form element must have a programmatically associated label element." }, schema: [ { type: "object", properties: { labelComponents: { type: "array", items: { type: "string" }, uniqueItems: true }, controlComponents: { type: "array", items: { type: "string" }, uniqueItems: true } } } ] }, create(context) { return (0, utils_1.defineTemplateBodyVisitor)(context, { VElement(node) { const options = context.options[0] || {}; const controlComponents = [ "input", "textarea", "select", "meter", "output", "progress", ...(options.controlComponents || []) ]; const elementType = (0, utils_1.getElementType)(node); if (!controlComponents.includes(elementType)) { return; } if (elementType === "input") { const type = (0, utils_1.getElementAttributeValue)(node, "type"); const types = ["hidden", "button", "image", "submit", "reset"]; if (!type || types.includes(type)) { return; } } if (!(0, utils_1.isAriaHidden)(node) && !(0, utils_1.hasAriaLabel)(node) && !hasNestedLabelElement(node, options) && !hasIdForLabelElement(node)) { context.report({ node, messageId: "default" }); } } }); } }; exports.default = rule;