jsx-no-duplicate-props.js 1.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. /**
  2. * @fileoverview Enforce no duplicate props
  3. * @author Markus Ånöstam
  4. */
  5. 'use strict';
  6. const has = require('object.hasown/polyfill')();
  7. const docsUrl = require('../util/docsUrl');
  8. const report = require('../util/report');
  9. // ------------------------------------------------------------------------------
  10. // Rule Definition
  11. // ------------------------------------------------------------------------------
  12. const messages = {
  13. noDuplicateProps: 'No duplicate props allowed',
  14. };
  15. module.exports = {
  16. meta: {
  17. docs: {
  18. description: 'Disallow duplicate properties in JSX',
  19. category: 'Possible Errors',
  20. recommended: true,
  21. url: docsUrl('jsx-no-duplicate-props'),
  22. },
  23. messages,
  24. schema: [{
  25. type: 'object',
  26. properties: {
  27. ignoreCase: {
  28. type: 'boolean',
  29. },
  30. },
  31. additionalProperties: false,
  32. }],
  33. },
  34. create(context) {
  35. const configuration = context.options[0] || {};
  36. const ignoreCase = configuration.ignoreCase || false;
  37. return {
  38. JSXOpeningElement(node) {
  39. const props = {};
  40. node.attributes.forEach((decl) => {
  41. if (decl.type === 'JSXSpreadAttribute') {
  42. return;
  43. }
  44. let name = decl.name.name;
  45. if (typeof name !== 'string') {
  46. return;
  47. }
  48. if (ignoreCase) {
  49. name = name.toLowerCase();
  50. }
  51. if (has(props, name)) {
  52. report(context, messages.noDuplicateProps, 'noDuplicateProps', {
  53. node: decl,
  54. });
  55. } else {
  56. props[name] = 1;
  57. }
  58. });
  59. },
  60. };
  61. },
  62. };