@bigbinary/eslint-plugin-neeto 1.5.0 → 1.5.1

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.
Files changed (3) hide show
  1. package/README.md +1 -0
  2. package/dist/index.js +127 -0
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -134,6 +134,7 @@ of the issues identified in JavaScript code.
134
134
  - [use-neetoui-classes](./docs/src/rules/use-neetoui-classes.md)
135
135
  - [use-permissions-prop-in-private-route](./docs/src/rules/use-permissions-prop-in-private-route.md)
136
136
  - [use-webpack-alias](./docs/src/rules/use-webpack-alias.md)
137
+ - [use-neetoui-action-block-in-formik-forms](./docs/src/rules/use-neetoui-action-block-in-formik-forms.md)
137
138
 
138
139
  ## Overriding rules
139
140
 
package/dist/index.js CHANGED
@@ -42,6 +42,7 @@
42
42
  var commonResolve$2 = loadJS$2("node_modules/@bigbinary/neeto-commons-frontend/configs/webpack/resolve.js");
43
43
  var resolve$2 = ramda.mergeDeepLeft(projectResolve$2, commonResolve$2);
44
44
  var rules = {
45
+ "@bigbinary/neeto/use-neetoui-action-block-in-formik-forms": "warn",
45
46
  "@bigbinary/neeto/no-unnecessary-classnames": "error",
46
47
  "@bigbinary/neeto/no-snake-case-destructuring-for-use-query-params-and-get-query-params": "warn",
47
48
  "@bigbinary/neeto/no-local-storage": "error",
@@ -588,6 +589,7 @@
588
589
  var USE_SHOW_THUMBS_UP_TOASTR_FUNCTION = "Use 'showThumbsUpToastr' function from '@bigbinary/neeto-commons-frontend/utils' for displaying thumbs up toast message.";
589
590
  var NO_UNNECESSARY_CLASSNAMES = "classnames usage is unnecessary";
590
591
  var USESTATE_DECLARATIONS_SHOULD_HAVE_INITIAL_VALUE = '"useState" declarations should have an initial value.';
592
+ var USE_NEETOUI_ACTION_BLOCK_IN_FORMIK_FORMS = 'Prefer using neetoui "ActionBlock" instead of "Button" for consistent behavior and appearance.';
591
593
 
592
594
  var PACKAGES_TO_CHECK = ["@bigbinary/neeto-molecules", "@bigbinary/neetoui", "@bigbinary/neeto-commons-frontend"];
593
595
 
@@ -9338,6 +9340,130 @@
9338
9340
  }
9339
9341
  };
9340
9342
 
9343
+ var CANCEL_BUTTON_STYLES = ["secondary", "text"];
9344
+ var SUBMIT_BUTTON_PATTERN = {
9345
+ type: TYPES.JSX_ELEMENT,
9346
+ openingElement: {
9347
+ name: {
9348
+ name: function name(_name) {
9349
+ var _name$toLowerCase;
9350
+ return _name === null || _name === void 0 ? void 0 : (_name$toLowerCase = _name.toLowerCase) === null || _name$toLowerCase === void 0 ? void 0 : _name$toLowerCase.call(_name).includes("button");
9351
+ }
9352
+ },
9353
+ attributes: neetoCist.existsBy({
9354
+ name: {
9355
+ name: "type"
9356
+ },
9357
+ value: {
9358
+ value: "submit"
9359
+ }
9360
+ })
9361
+ }
9362
+ };
9363
+ var CANCEL_BUTTON_PATTERN = {
9364
+ type: TYPES.JSX_ELEMENT,
9365
+ openingElement: {
9366
+ name: {
9367
+ name: function name(_name2) {
9368
+ var _name2$toLowerCase;
9369
+ return _name2 === null || _name2 === void 0 ? void 0 : (_name2$toLowerCase = _name2.toLowerCase) === null || _name2$toLowerCase === void 0 ? void 0 : _name2$toLowerCase.call(_name2).includes("button");
9370
+ }
9371
+ },
9372
+ attributes: neetoCist.existsBy({
9373
+ name: {
9374
+ name: "style"
9375
+ },
9376
+ value: {
9377
+ value: function value(_value) {
9378
+ return CANCEL_BUTTON_STYLES.includes(_value);
9379
+ }
9380
+ }
9381
+ })
9382
+ }
9383
+ };
9384
+ var BUTTON_NODE_PATTERN = {
9385
+ type: TYPES.JSX_EXPRESSION_CONTAINER,
9386
+ expression: matchesAny([{
9387
+ type: TYPES.LOGICAL_EXPRESSION,
9388
+ right: matchesAny([SUBMIT_BUTTON_PATTERN, CANCEL_BUTTON_PATTERN])
9389
+ }, {
9390
+ type: TYPES.CONDITIONAL_EXPRESSION,
9391
+ consequent: matchesAny([SUBMIT_BUTTON_PATTERN, CANCEL_BUTTON_PATTERN])
9392
+ }])
9393
+ };
9394
+ var CONDITIONAL_NODE_TYPES = [TYPES.LOGICAL_EXPRESSION, TYPES.CONDITIONAL_EXPRESSION];
9395
+ var NODE_TYPES = [TYPES.JSX_ELEMENT, TYPES.JSX_EXPRESSION_CONTAINER];
9396
+
9397
+ var isFormActionButton = function isFormActionButton(node) {
9398
+ return matchesAny([BUTTON_NODE_PATTERN, SUBMIT_BUTTON_PATTERN, CANCEL_BUTTON_PATTERN], node);
9399
+ };
9400
+ var isFormSubmitButton = function isFormSubmitButton(node) {
9401
+ return neetoCist.matches(SUBMIT_BUTTON_PATTERN, node);
9402
+ };
9403
+ var isAlternateNode = function isAlternateNode(node) {
9404
+ return neetoCist.matches({
9405
+ alternate: {
9406
+ loc: {
9407
+ start: {
9408
+ line: node.loc.start.line
9409
+ }
9410
+ }
9411
+ }
9412
+ }, node.parent);
9413
+ };
9414
+ var getAdjacentActionNode = function getAdjacentActionNode(node) {
9415
+ var _node$parent, _node$parent$parent, _filterBy2, _findIndexBy2;
9416
+ var isSucceedingNode = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
9417
+ var parentNode = CONDITIONAL_NODE_TYPES.includes(node.parent.type) ? (_node$parent = node.parent) === null || _node$parent === void 0 ? void 0 : (_node$parent$parent = _node$parent.parent) === null || _node$parent$parent === void 0 ? void 0 : _node$parent$parent.parent : node.parent;
9418
+ if (neetoCist.isNotPresent(parentNode)) return null;
9419
+ var jsxElementsInCurrentContainer = (_filterBy2 = neetoCist._filterBy({
9420
+ type: function type(_type) {
9421
+ return NODE_TYPES.includes(_type);
9422
+ }
9423
+ }, parentNode.children)) !== null && _filterBy2 !== void 0 ? _filterBy2 : [];
9424
+ var nodeStartLineNumber = CONDITIONAL_NODE_TYPES.includes(node.parent.type) ? node.parent.loc.start.line : node.loc.start.line;
9425
+ var currentNodeIndex = (_findIndexBy2 = neetoCist._findIndexBy({
9426
+ loc: {
9427
+ start: {
9428
+ line: nodeStartLineNumber
9429
+ }
9430
+ }
9431
+ }, jsxElementsInCurrentContainer)) !== null && _findIndexBy2 !== void 0 ? _findIndexBy2 : -1;
9432
+ var adjacentNodeIndex = isSucceedingNode ? currentNodeIndex + 1 : currentNodeIndex - 1;
9433
+ var adjacentNode = jsxElementsInCurrentContainer[adjacentNodeIndex];
9434
+ return isFormActionButton(adjacentNode) ? adjacentNode : null;
9435
+ };
9436
+
9437
+ var useNeetouiActionBlockInFormikForms = {
9438
+ meta: {
9439
+ type: "suggestion",
9440
+ docs: {
9441
+ url: "https://github.com/bigbinary/eslint-plugin-neeto/blob/main/docs/src/rules/use-neetoui-action-block-in-formik-forms.md",
9442
+ description: "Enforces the usage of neetoui `ActionBlock` component in Formik forms instead of custom buttons for submit and cancel actions."
9443
+ }
9444
+ },
9445
+ create: function create(context) {
9446
+ return {
9447
+ JSXElement: function JSXElement(node) {
9448
+ if (!isFormSubmitButton(node) || isAlternateNode(node)) return;
9449
+ var succeedingButton = getAdjacentActionNode(node, true);
9450
+ var precedingButton = getAdjacentActionNode(node);
9451
+ var start = node.loc.start;
9452
+ var end = node.loc.end;
9453
+ if (neetoCist.isPresent(precedingButton)) start = precedingButton.loc.start;
9454
+ if (neetoCist.isPresent(succeedingButton)) end = succeedingButton.loc.end;
9455
+ context.report({
9456
+ loc: {
9457
+ start: start,
9458
+ end: end
9459
+ },
9460
+ message: USE_NEETOUI_ACTION_BLOCK_IN_FORMIK_FORMS
9461
+ });
9462
+ }
9463
+ };
9464
+ }
9465
+ };
9466
+
9341
9467
  var COLORS = ["black", "white", "gray", "red", "yellow", "green", "blue", "indigo", "purple", "pink"];
9342
9468
  var SIZES = ["none", "sm", "md", "lg", "xl", "2xl", "3xl", "full"];
9343
9469
  var BORDER_COLOR_PATTERNS = COLORS.map(function (color) {
@@ -10620,6 +10746,7 @@
10620
10746
 
10621
10747
  var index = {
10622
10748
  rules: {
10749
+ "use-neetoui-action-block-in-formik-forms": useNeetouiActionBlockInFormikForms,
10623
10750
  "no-unnecessary-classnames": noUnnecessaryClassnames,
10624
10751
  "no-snake-case-destructuring-for-use-query-params-and-get-query-params": noSnakeCaseDestructuringForUseQueryParamsAndGetQueryParams,
10625
10752
  "no-local-storage": noLocalStorage,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bigbinary/eslint-plugin-neeto",
3
- "version": "1.5.0",
3
+ "version": "1.5.1",
4
4
  "main": "dist/index.js",
5
5
  "license": "UNLICENSED",
6
6
  "scripts": {