diff --git a/README.md b/README.md
index 9e0d5d3ae..02f1ed5c0 100644
--- a/README.md
+++ b/README.md
@@ -89,15 +89,15 @@ Add `plugin:jsx-a11y/recommended` or `plugin:jsx-a11y/strict` in `extends`:
}
```
-> As you are extending our configuration, you can omit `"plugins": ["jsx-a11y"]` from your `.eslintrc` configuration file.
+### Configurations
-To enable your custom components to be checked as DOM elements, you can set global settings in your
-configuration file by mapping each custom component name to a DOM element type.
+> As you are extending our configuration, you can omit `"plugins": ["jsx-a11y"]` from your `.eslintrc` configuration file.
```json
{
"settings": {
"jsx-a11y": {
+ "polymorphicPropName": "as",
"components": {
"CityInput": "input",
"CustomButton": "button",
@@ -109,6 +109,23 @@ configuration file by mapping each custom component name to a DOM element type.
}
```
+#### Component Mapping
+
+To enable your custom components to be checked as DOM elements, you can set global settings in your configuration file by mapping each custom component name to a DOM element type.
+
+#### Polymorphic Components
+
+You can optionally use the `polymorphicPropName` setting to define the prop your code uses to create polymorphic components.
+This setting will be used determine the element type in rules that require semantic context.
+
+For example, if you set the `polymorphicPropName` setting to `as` then this element:
+
+`Configurations `
+
+will be evaluated as an `h3`. If no `polymorphicPropName` is set, then the component will be evaluated as `Box`.
+
+⚠️ Polymorphic components can make code harder to maintain; please use this feature with caution.
+
## Supported Rules
diff --git a/__tests__/src/rules/accessible-emoji-test.js b/__tests__/src/rules/accessible-emoji-test.js
index a1d21f461..fc6e95a10 100644
--- a/__tests__/src/rules/accessible-emoji-test.js
+++ b/__tests__/src/rules/accessible-emoji-test.js
@@ -43,6 +43,10 @@ ruleTester.run('accessible-emoji', rule, {
code: '🐼',
settings: { 'jsx-a11y': { components: { CustomInput: 'input' } } },
},
+ {
+ code: '🐼',
+ settings: { 'jsx-a11y': { polymorphicPropName: 'as' } },
+ },
)).map(parserOptionsMapper),
invalid: parsers.all([].concat(
{ code: '🐼', errors: [expectedError] },
@@ -53,5 +57,10 @@ ruleTester.run('accessible-emoji', rule, {
{ code: '🐼', errors: [expectedError] },
{ code: '🐼', errors: [expectedError] },
{ code: '🐼', errors: [expectedError] },
+ {
+ code: '🐼',
+ settings: { 'jsx-a11y': { polymorphicPropName: 'as' } },
+ errors: [expectedError],
+ },
)).map(parserOptionsMapper),
});
diff --git a/__tests__/src/rules/alt-text-test.js b/__tests__/src/rules/alt-text-test.js
index 07b2c8259..24e36e23d 100644
--- a/__tests__/src/rules/alt-text-test.js
+++ b/__tests__/src/rules/alt-text-test.js
@@ -55,6 +55,7 @@ const inputImageError = {
const componentsSettings = {
'jsx-a11y': {
+ polymorphicPropName: 'as',
components: {
Input: 'input',
},
@@ -132,6 +133,7 @@ ruleTester.run('alt-text', rule, {
{ code: '' },
{ code: '' },
{ code: '', settings: componentsSettings },
+ { code: '', settings: componentsSettings },
// CUSTOM ELEMENT TESTS FOR ARRAY OPTION TESTS
{ code: ';', options: array },
@@ -195,6 +197,7 @@ ruleTester.run('alt-text', rule, {
{ code: '', errors: [ariaLabelledbyValueError] },
{ code: '', errors: [ariaLabelValueError] },
{ code: '', errors: [ariaLabelledbyValueError] },
+ { code: '', settings: componentsSettings, errors: [ariaLabelValueError] },
// DEFAULT ELEMENT 'object' TESTS
{ code: '', errors: [objectError] },
diff --git a/__tests__/src/rules/aria-role-test.js b/__tests__/src/rules/aria-role-test.js
index 410749666..9a8ec3a89 100644
--- a/__tests__/src/rules/aria-role-test.js
+++ b/__tests__/src/rules/aria-role-test.js
@@ -50,6 +50,7 @@ const ignoreNonDOMSchema = [{
const customDivSettings = {
'jsx-a11y': {
+ polymorphicPropName: 'asChild',
components: {
Div: 'div',
},
@@ -79,6 +80,10 @@ ruleTester.run('aria-role', rule, {
code: '