source: frontend/node_modules/eslint-plugin-jsx-a11y/lib/rules/label-has-associated-control.js

Last change on this file was 9af201e, checked in by MBK <marija.karapandzova@…>, 2 weeks ago

Fix frontend appearance

  • Property mode set to 100644
File size: 4.6 KB
Line 
1"use strict";
2
3Object.defineProperty(exports, "__esModule", {
4 value: true
5});
6exports["default"] = void 0;
7var _jsxAstUtils = require("jsx-ast-utils");
8var _schemas = require("../util/schemas");
9var _getElementType = _interopRequireDefault(require("../util/getElementType"));
10var _mayContainChildComponent = _interopRequireDefault(require("../util/mayContainChildComponent"));
11var _mayHaveAccessibleLabel = _interopRequireDefault(require("../util/mayHaveAccessibleLabel"));
12function _interopRequireDefault(e) { return e && e.__esModule ? e : { "default": e }; }
13/**
14 * @fileoverview Enforce label tags have an associated control.
15 * @author Jesse Beach
16 *
17 *
18 */
19
20// ----------------------------------------------------------------------------
21// Rule Definition
22// ----------------------------------------------------------------------------
23
24var errorMessage = 'A form label must be associated with a control.';
25var errorMessageNoLabel = 'A form label must have accessible text.';
26var schema = (0, _schemas.generateObjSchema)({
27 labelComponents: _schemas.arraySchema,
28 labelAttributes: _schemas.arraySchema,
29 controlComponents: _schemas.arraySchema,
30 assert: {
31 description: 'Assert that the label has htmlFor, a nested label, both or either',
32 type: 'string',
33 "enum": ['htmlFor', 'nesting', 'both', 'either']
34 },
35 depth: {
36 description: 'JSX tree depth limit to check for accessible label',
37 type: 'integer',
38 minimum: 0
39 }
40});
41function validateID(node, context) {
42 var _settings$jsxA11y$at, _settings$jsxA11y, _settings$jsxA11y$att;
43 var settings = context.settings;
44 var htmlForAttributes = (_settings$jsxA11y$at = (_settings$jsxA11y = settings['jsx-a11y']) === null || _settings$jsxA11y === void 0 ? void 0 : (_settings$jsxA11y$att = _settings$jsxA11y.attributes) === null || _settings$jsxA11y$att === void 0 ? void 0 : _settings$jsxA11y$att["for"]) !== null && _settings$jsxA11y$at !== void 0 ? _settings$jsxA11y$at : ['htmlFor'];
45 for (var i = 0; i < htmlForAttributes.length; i += 1) {
46 var attribute = htmlForAttributes[i];
47 if ((0, _jsxAstUtils.hasProp)(node.attributes, attribute)) {
48 var htmlForAttr = (0, _jsxAstUtils.getProp)(node.attributes, attribute);
49 var htmlForValue = (0, _jsxAstUtils.getPropValue)(htmlForAttr);
50 return htmlForAttr !== false && !!htmlForValue;
51 }
52 }
53 return false;
54}
55var _default = exports["default"] = {
56 meta: {
57 docs: {
58 description: 'Enforce that a `label` tag has a text label and an associated control.',
59 url: 'https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/main/docs/rules/label-has-associated-control.md'
60 },
61 schema: [schema]
62 },
63 create: function create(context) {
64 var options = context.options[0] || {};
65 var labelComponents = options.labelComponents || [];
66 var assertType = options.assert || 'either';
67 var componentNames = ['label'].concat(labelComponents);
68 var elementType = (0, _getElementType["default"])(context);
69 var rule = function rule(node) {
70 if (componentNames.indexOf(elementType(node.openingElement)) === -1) {
71 return;
72 }
73 var controlComponents = ['input', 'meter', 'output', 'progress', 'select', 'textarea'].concat(options.controlComponents || []);
74 // Prevent crazy recursion.
75 var recursionDepth = Math.min(options.depth === undefined ? 2 : options.depth, 25);
76 var hasLabelId = validateID(node.openingElement, context);
77 // Check for multiple control components.
78 var hasNestedControl = controlComponents.some(function (name) {
79 return (0, _mayContainChildComponent["default"])(node, name, recursionDepth, elementType);
80 });
81 var hasAccessibleLabel = (0, _mayHaveAccessibleLabel["default"])(node, recursionDepth, options.labelAttributes, elementType, controlComponents);
82 if (!hasAccessibleLabel) {
83 context.report({
84 node: node.openingElement,
85 message: errorMessageNoLabel
86 });
87 return;
88 }
89 switch (assertType) {
90 case 'htmlFor':
91 if (hasLabelId) {
92 return;
93 }
94 break;
95 case 'nesting':
96 if (hasNestedControl) {
97 return;
98 }
99 break;
100 case 'both':
101 if (hasLabelId && hasNestedControl) {
102 return;
103 }
104 break;
105 case 'either':
106 if (hasLabelId || hasNestedControl) {
107 return;
108 }
109 break;
110 default:
111 break;
112 }
113
114 // htmlFor case
115 context.report({
116 node: node.openingElement,
117 message: errorMessage
118 });
119 };
120
121 // Create visitor selectors.
122 return {
123 JSXElement: rule
124 };
125 }
126};
127module.exports = exports.default;
Note: See TracBrowser for help on using the repository browser.