forbid-component-props.js 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. /**
  2. * @fileoverview Forbid certain props on components
  3. * @author Joe Lencioni
  4. */
  5. 'use strict';
  6. const docsUrl = require('../util/docsUrl');
  7. // ------------------------------------------------------------------------------
  8. // Constants
  9. // ------------------------------------------------------------------------------
  10. const DEFAULTS = ['className', 'style'];
  11. // ------------------------------------------------------------------------------
  12. // Rule Definition
  13. // ------------------------------------------------------------------------------
  14. module.exports = {
  15. meta: {
  16. docs: {
  17. description: 'Forbid certain props on components',
  18. category: 'Best Practices',
  19. recommended: false,
  20. url: docsUrl('forbid-component-props')
  21. },
  22. schema: [{
  23. type: 'object',
  24. properties: {
  25. forbid: {
  26. type: 'array',
  27. items: {
  28. oneOf: [{
  29. type: 'string'
  30. }, {
  31. type: 'object',
  32. properties: {
  33. propName: {
  34. type: 'string'
  35. },
  36. allowedFor: {
  37. type: 'array',
  38. uniqueItems: true,
  39. items: {
  40. type: 'string'
  41. }
  42. }
  43. }
  44. }]
  45. }
  46. }
  47. }
  48. }]
  49. },
  50. create: function(context) {
  51. const configuration = context.options[0] || {};
  52. const forbid = new Map((configuration.forbid || DEFAULTS).map(value => {
  53. const propName = typeof value === 'string' ? value : value.propName;
  54. const whitelist = typeof value === 'string' ? [] : (value.allowedFor || []);
  55. return [propName, whitelist];
  56. }));
  57. function isForbidden(prop, tagName) {
  58. const whitelist = forbid.get(prop);
  59. // if the tagName is undefined (`<this.something>`), we assume it's a forbidden element
  60. return typeof whitelist !== 'undefined' && (typeof tagName === 'undefined' || whitelist.indexOf(tagName) === -1);
  61. }
  62. return {
  63. JSXAttribute: function(node) {
  64. const tag = node.parent.name.name;
  65. if (tag && tag[0] !== tag[0].toUpperCase()) {
  66. // This is a DOM node, not a Component, so exit.
  67. return;
  68. }
  69. const prop = node.name.name;
  70. if (!isForbidden(prop, tag)) {
  71. return;
  72. }
  73. context.report({
  74. node: node,
  75. message: `Prop \`${prop}\` is forbidden on Components`
  76. });
  77. }
  78. };
  79. }
  80. };