@bigbinary/eslint-plugin-neeto 1.7.6 → 1.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -0
- package/dist/index.js +142 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -140,6 +140,7 @@ of the issues identified in JavaScript code.
|
|
|
140
140
|
- [use-permissions-prop-in-private-route](./docs/src/rules/use-permissions-prop-in-private-route.md)
|
|
141
141
|
- [use-webpack-alias](./docs/src/rules/use-webpack-alias.md)
|
|
142
142
|
- [use-neetoui-action-block-in-formik-forms](./docs/src/rules/use-neetoui-action-block-in-formik-forms.md)
|
|
143
|
+
- [prefer-radio-buttons-for-few-options](./docs/src/rules/prefer-radio-buttons-for-few-options.md)
|
|
143
144
|
|
|
144
145
|
## Overriding rules
|
|
145
146
|
|
package/dist/index.js
CHANGED
|
@@ -38,6 +38,7 @@
|
|
|
38
38
|
var commonResolve$2 = loadJS$2("node_modules/@bigbinary/neeto-commons-frontend/configs/webpack/resolve.js");
|
|
39
39
|
var resolve$2 = ramda.mergeDeepLeft(projectResolve$2, commonResolve$2);
|
|
40
40
|
var rules = {
|
|
41
|
+
"@bigbinary/neeto/prefer-radio-buttons-for-few-options": "warn",
|
|
41
42
|
"@bigbinary/neeto/switch-children-must-be-route-or-redirect": "error",
|
|
42
43
|
"@bigbinary/neeto/use-dayjs-from-neeto-commons-fronted": "error",
|
|
43
44
|
"@bigbinary/neeto/use-neetoui-action-block-in-formik-forms": "warn",
|
|
@@ -330,7 +331,7 @@
|
|
|
330
331
|
}
|
|
331
332
|
|
|
332
333
|
var name = "@bigbinary/eslint-plugin-neeto";
|
|
333
|
-
var version = "1.7.
|
|
334
|
+
var version = "1.7.6";
|
|
334
335
|
var main = "dist/index.js";
|
|
335
336
|
var license = "UNLICENSED";
|
|
336
337
|
var scripts = {
|
|
@@ -753,6 +754,7 @@
|
|
|
753
754
|
var HELP_URL_SHOULD_USE_PERMALINK = "Help URL must use a permalink (/p/...) instead of an article link (/articles/...).";
|
|
754
755
|
var HELP_URL_INCORRECT_FORMAT = "Incorrect help URL format. Please use the 'help.neeto<product>.com' format instead of 'neeto<product>help.neetokb.com'.";
|
|
755
756
|
var INVALID_SWITCH_CHILD_MESSAGE = "Switch component can only contain Route, Redirect, or PrivateRoute as direct children";
|
|
757
|
+
var PREFER_RADIO_BUTTONS_FOR_FEW_OPTIONS = "Consider using Radio buttons instead of Dropdown/Select when there are fewer than 4 options.";
|
|
756
758
|
|
|
757
759
|
var PACKAGES_TO_CHECK = ["@bigbinary/neeto-molecules", "@bigbinary/neetoui", "@bigbinary/neeto-commons-frontend"];
|
|
758
760
|
|
|
@@ -9174,6 +9176,144 @@
|
|
|
9174
9176
|
}
|
|
9175
9177
|
};
|
|
9176
9178
|
|
|
9179
|
+
var MIN_OPTIONS_THRESHOLD = 4;
|
|
9180
|
+
var DROPDOWN_COMPONENT_NAMES = ["Dropdown", "Select", "DropdownMenu", "SelectInput", "MultiSelect", "Menu"];
|
|
9181
|
+
var OPTION_ELEMENT_NAMES = ["option", "Option", "MenuItem", "MenuItemButton"];
|
|
9182
|
+
var DROPDOWN_COMPONENT_PATTERN = {
|
|
9183
|
+
type: TYPES.JSX_ELEMENT,
|
|
9184
|
+
openingElement: {
|
|
9185
|
+
type: TYPES.JSX_OPENING_ELEMENT,
|
|
9186
|
+
name: {
|
|
9187
|
+
type: TYPES.JSX_IDENTIFIER,
|
|
9188
|
+
name: ramda.includes(ramda.__, DROPDOWN_COMPONENT_NAMES)
|
|
9189
|
+
}
|
|
9190
|
+
}
|
|
9191
|
+
};
|
|
9192
|
+
var OPTION_ELEMENT_PATTERN = {
|
|
9193
|
+
type: TYPES.JSX_ELEMENT,
|
|
9194
|
+
openingElement: {
|
|
9195
|
+
type: TYPES.JSX_OPENING_ELEMENT,
|
|
9196
|
+
name: {
|
|
9197
|
+
type: TYPES.JSX_IDENTIFIER,
|
|
9198
|
+
name: ramda.includes(ramda.__, OPTION_ELEMENT_NAMES)
|
|
9199
|
+
}
|
|
9200
|
+
}
|
|
9201
|
+
};
|
|
9202
|
+
var OPTIONS_ARRAY_PATTERN = {
|
|
9203
|
+
type: TYPES.JSX_ATTRIBUTE,
|
|
9204
|
+
name: {
|
|
9205
|
+
type: TYPES.JSX_IDENTIFIER,
|
|
9206
|
+
name: "options"
|
|
9207
|
+
},
|
|
9208
|
+
value: {
|
|
9209
|
+
type: TYPES.JSX_EXPRESSION_CONTAINER
|
|
9210
|
+
}
|
|
9211
|
+
};
|
|
9212
|
+
var SPREAD_ATTRIBUTE_PATTERN = {
|
|
9213
|
+
type: TYPES.JSX_SPREAD_ATTRIBUTE,
|
|
9214
|
+
argument: {
|
|
9215
|
+
type: TYPES.OBJECT_EXPRESSION
|
|
9216
|
+
}
|
|
9217
|
+
};
|
|
9218
|
+
var SPREAD_OPTION_PROPERTY_PATTERN = {
|
|
9219
|
+
type: TYPES.PROPERTY,
|
|
9220
|
+
key: {
|
|
9221
|
+
type: TYPES.IDENTIFIER,
|
|
9222
|
+
name: "options"
|
|
9223
|
+
}
|
|
9224
|
+
};
|
|
9225
|
+
|
|
9226
|
+
var isImportedVariable = function isImportedVariable(node, context) {
|
|
9227
|
+
if (node.type !== TYPES.IDENTIFIER) return false;
|
|
9228
|
+
var scope = context.sourceCode.getScope(node);
|
|
9229
|
+
var variable = scope.set.get(node.name);
|
|
9230
|
+
if (!variable || ramda.isEmpty(variable.defs)) return false;
|
|
9231
|
+
var def = variable.defs[0];
|
|
9232
|
+
return def.type === "ImportBinding";
|
|
9233
|
+
};
|
|
9234
|
+
var resolveVariableReference = function resolveVariableReference(node, context) {
|
|
9235
|
+
var _def$node;
|
|
9236
|
+
if (node.type !== TYPES.IDENTIFIER) return null;
|
|
9237
|
+
var scope = context.sourceCode.getScope(node);
|
|
9238
|
+
var variable = scope.set.get(node.name);
|
|
9239
|
+
if (!variable || ramda.isEmpty(variable.defs)) return null;
|
|
9240
|
+
var def = variable.defs[0];
|
|
9241
|
+
return ((_def$node = def.node) === null || _def$node === void 0 ? void 0 : _def$node.init) || null;
|
|
9242
|
+
};
|
|
9243
|
+
var countArrayElements = function countArrayElements(node, context) {
|
|
9244
|
+
if (node.type === TYPES.ARRAY_EXPRESSION) {
|
|
9245
|
+
return node.elements ? node.elements.length : 0;
|
|
9246
|
+
}
|
|
9247
|
+
if (node.type === TYPES.IDENTIFIER) {
|
|
9248
|
+
if (isImportedVariable(node, context)) return -1;
|
|
9249
|
+
var resolvedNode = resolveVariableReference(node, context);
|
|
9250
|
+
if (resolvedNode) {
|
|
9251
|
+
return countArrayElements(resolvedNode, context);
|
|
9252
|
+
}
|
|
9253
|
+
}
|
|
9254
|
+
return 0;
|
|
9255
|
+
};
|
|
9256
|
+
var countOptions = function countOptions(node, context) {
|
|
9257
|
+
var _node$openingElement, _optionsAttribute$val;
|
|
9258
|
+
var optionCount = 0;
|
|
9259
|
+
|
|
9260
|
+
// Count direct option children
|
|
9261
|
+
if (node.children) {
|
|
9262
|
+
var optionElements = node.children.filter(function (child) {
|
|
9263
|
+
return neetoCist.matches(OPTION_ELEMENT_PATTERN, child);
|
|
9264
|
+
});
|
|
9265
|
+
optionCount += optionElements.length;
|
|
9266
|
+
}
|
|
9267
|
+
var attributes = node === null || node === void 0 ? void 0 : (_node$openingElement = node.openingElement) === null || _node$openingElement === void 0 ? void 0 : _node$openingElement.attributes;
|
|
9268
|
+
if (!attributes) return optionCount;
|
|
9269
|
+
|
|
9270
|
+
// Count options from props passed to the component
|
|
9271
|
+
var optionsAttribute = ramda.find(neetoCist.matches(OPTIONS_ARRAY_PATTERN), attributes);
|
|
9272
|
+
var expression = optionsAttribute === null || optionsAttribute === void 0 ? void 0 : (_optionsAttribute$val = optionsAttribute.value) === null || _optionsAttribute$val === void 0 ? void 0 : _optionsAttribute$val.expression;
|
|
9273
|
+
if (expression) {
|
|
9274
|
+
var elementsCount = countArrayElements(expression, context);
|
|
9275
|
+
optionCount += elementsCount;
|
|
9276
|
+
}
|
|
9277
|
+
|
|
9278
|
+
// Count options from spread props eg: <Component {...{options}} />
|
|
9279
|
+
var spreadAttributes = attributes.filter(function (attribute) {
|
|
9280
|
+
return neetoCist.matches(SPREAD_ATTRIBUTE_PATTERN, attribute);
|
|
9281
|
+
});
|
|
9282
|
+
spreadAttributes.forEach(function (attribute) {
|
|
9283
|
+
if (!attribute.argument) return;
|
|
9284
|
+
if (!(attribute.argument.type === TYPES.OBJECT_EXPRESSION)) return;
|
|
9285
|
+
var optionsProperty = ramda.find(neetoCist.matches(SPREAD_OPTION_PROPERTY_PATTERN), attribute.argument.properties);
|
|
9286
|
+
var optionsPropertyValue = optionsProperty === null || optionsProperty === void 0 ? void 0 : optionsProperty.value;
|
|
9287
|
+
if (!optionsPropertyValue) return;
|
|
9288
|
+
var elementsCount = countArrayElements(optionsPropertyValue, context);
|
|
9289
|
+
optionCount += elementsCount;
|
|
9290
|
+
});
|
|
9291
|
+
return optionCount;
|
|
9292
|
+
};
|
|
9293
|
+
var preferRadioButtonsForFewOptions = {
|
|
9294
|
+
meta: {
|
|
9295
|
+
type: "warn",
|
|
9296
|
+
docs: {
|
|
9297
|
+
url: "https://github.com/bigbinary/eslint-plugin-neeto/blob/main/docs/src/rules/prefer-radio-buttons-for-few-options.md",
|
|
9298
|
+
description: PREFER_RADIO_BUTTONS_FOR_FEW_OPTIONS
|
|
9299
|
+
}
|
|
9300
|
+
},
|
|
9301
|
+
create: function create(context) {
|
|
9302
|
+
return {
|
|
9303
|
+
JSXElement: function JSXElement(node) {
|
|
9304
|
+
if (!neetoCist.matches(DROPDOWN_COMPONENT_PATTERN, node)) return;
|
|
9305
|
+
var optionCount = countOptions(node, context);
|
|
9306
|
+
if (optionCount > 0 && optionCount < MIN_OPTIONS_THRESHOLD) {
|
|
9307
|
+
context.report({
|
|
9308
|
+
node: node,
|
|
9309
|
+
message: PREFER_RADIO_BUTTONS_FOR_FEW_OPTIONS
|
|
9310
|
+
});
|
|
9311
|
+
}
|
|
9312
|
+
}
|
|
9313
|
+
};
|
|
9314
|
+
}
|
|
9315
|
+
};
|
|
9316
|
+
|
|
9177
9317
|
var NEETO_PACKAGES = ["@bigbinary/neetoui", "@bigbinary/neeto-icons"];
|
|
9178
9318
|
|
|
9179
9319
|
var importedFromNeeto = function importedFromNeeto(context, node) {
|
|
@@ -13309,6 +13449,7 @@
|
|
|
13309
13449
|
|
|
13310
13450
|
var index = {
|
|
13311
13451
|
rules: {
|
|
13452
|
+
"prefer-radio-buttons-for-few-options": preferRadioButtonsForFewOptions,
|
|
13312
13453
|
"switch-children-must-be-route-or-redirect": switchChildrenMustBeRouteOrRedirect,
|
|
13313
13454
|
"use-dayjs-from-neeto-commons-fronted": useDayjsFromNeetoCommonsFronted,
|
|
13314
13455
|
"use-neetoui-action-block-in-formik-forms": useNeetouiActionBlockInFormikForms,
|