@hero-design/eslint-plugin 9.0.1 → 9.1.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/CHANGELOG.md +6 -0
- package/eslint.config.js +31 -0
- package/lib/index.js +2 -1
- package/lib/rules/react-no-text-outside-typography.js +216 -0
- package/package.json +6 -3
- package/tests/lib/rules/react-no-text-outside-typography.js +248 -0
- package/.eslintrc.js +0 -19
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
# @hero-design/eslint-plugin
|
|
2
2
|
|
|
3
|
+
## 9.1.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- [#3197](https://github.com/Thinkei/hero-design/pull/3197) [`36c71a4a7`](https://github.com/Thinkei/hero-design/commit/36c71a4a7719bd5f09925a9d88e197135696d0c9) Thanks [@vinhphan-eh](https://github.com/vinhphan-eh)! - Add react-no-text-outside-typography rule for react
|
|
8
|
+
|
|
3
9
|
## 9.0.1
|
|
4
10
|
|
|
5
11
|
### Patch Changes
|
package/eslint.config.js
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
const { FlatCompat } = require('@eslint/eslintrc');
|
|
2
|
+
const js = require('@eslint/js');
|
|
3
|
+
|
|
4
|
+
const compat = new FlatCompat({
|
|
5
|
+
baseDirectory: __dirname,
|
|
6
|
+
recommendedConfig: js.configs.recommended,
|
|
7
|
+
});
|
|
8
|
+
|
|
9
|
+
module.exports = [
|
|
10
|
+
...compat.extends(
|
|
11
|
+
'eslint:recommended',
|
|
12
|
+
'plugin:eslint-plugin/recommended',
|
|
13
|
+
'plugin:node/recommended'
|
|
14
|
+
),
|
|
15
|
+
{
|
|
16
|
+
files: ['**/*.js', '**/*.ts'],
|
|
17
|
+
languageOptions: {
|
|
18
|
+
globals: {
|
|
19
|
+
node: true,
|
|
20
|
+
},
|
|
21
|
+
},
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
files: ['tests/**/*.js'],
|
|
25
|
+
languageOptions: {
|
|
26
|
+
globals: {
|
|
27
|
+
jest: true,
|
|
28
|
+
},
|
|
29
|
+
},
|
|
30
|
+
},
|
|
31
|
+
];
|
package/lib/index.js
CHANGED
|
@@ -121,7 +121,8 @@ module.exports = {
|
|
|
121
121
|
recommendedReact: {
|
|
122
122
|
plugins: ['@hero-design'],
|
|
123
123
|
rules: {
|
|
124
|
-
'@hero-design/no-direct-color-palette-access': 'error'
|
|
124
|
+
'@hero-design/no-direct-color-palette-access': 'error',
|
|
125
|
+
'@hero-design/react-no-text-outside-typography': 'warn',
|
|
125
126
|
}
|
|
126
127
|
}
|
|
127
128
|
},
|
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
const notRecommendedList = [
|
|
2
|
+
'div',
|
|
3
|
+
'p',
|
|
4
|
+
'span',
|
|
5
|
+
'h1',
|
|
6
|
+
'h2',
|
|
7
|
+
'h3',
|
|
8
|
+
'h4',
|
|
9
|
+
'h5',
|
|
10
|
+
'h6',
|
|
11
|
+
'a',
|
|
12
|
+
'strong',
|
|
13
|
+
'em',
|
|
14
|
+
'b',
|
|
15
|
+
'i',
|
|
16
|
+
'u',
|
|
17
|
+
];
|
|
18
|
+
|
|
19
|
+
// Get the parent tag name of the node
|
|
20
|
+
const getParentTagName = (node) => {
|
|
21
|
+
let parent = node.parent;
|
|
22
|
+
while (parent) {
|
|
23
|
+
if (parent.type === 'JSXElement') {
|
|
24
|
+
return parent.openingElement.name.name;
|
|
25
|
+
}
|
|
26
|
+
parent = parent.parent;
|
|
27
|
+
}
|
|
28
|
+
return null;
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
// Find the Typography component in the parent hierarchy
|
|
32
|
+
// and return the value of tagName prop and the level of nested component
|
|
33
|
+
const findTypography = (node, typographyNames) => {
|
|
34
|
+
let parent = node.parent;
|
|
35
|
+
let level = 0;
|
|
36
|
+
let tagName = null;
|
|
37
|
+
let found = false;
|
|
38
|
+
|
|
39
|
+
while (parent) {
|
|
40
|
+
if (
|
|
41
|
+
parent.type === 'JSXElement' &&
|
|
42
|
+
parent.openingElement.name.type === 'JSXMemberExpression' &&
|
|
43
|
+
typographyNames.includes(parent.openingElement.name.object.name)
|
|
44
|
+
) {
|
|
45
|
+
found = true;
|
|
46
|
+
const attributes = parent.openingElement.attributes;
|
|
47
|
+
for (let attr of attributes) {
|
|
48
|
+
if (attr.name && attr.name.name === 'tagName') {
|
|
49
|
+
tagName = attr.value.value;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
break;
|
|
53
|
+
}
|
|
54
|
+
parent = parent.parent;
|
|
55
|
+
level++;
|
|
56
|
+
}
|
|
57
|
+
return { tagName, level, found };
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
// Check if the direct parent element is in the notRecommendedList
|
|
61
|
+
const isParentNotRecommended = (node) => {
|
|
62
|
+
let parentElement = node.parent;
|
|
63
|
+
while (parentElement && parentElement.type !== 'JSXElement') {
|
|
64
|
+
parentElement = parentElement.parent;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
return (
|
|
68
|
+
parentElement &&
|
|
69
|
+
parentElement.openingElement.name.type === 'JSXIdentifier' &&
|
|
70
|
+
notRecommendedList.includes(parentElement.openingElement.name.name)
|
|
71
|
+
);
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
const checkNode = (node, context, typographyNames) => {
|
|
75
|
+
const {
|
|
76
|
+
tagName,
|
|
77
|
+
level,
|
|
78
|
+
found: foundTypography,
|
|
79
|
+
} = findTypography(node, typographyNames);
|
|
80
|
+
|
|
81
|
+
// Typography not found, check if the direct parent is in the notRecommendedList
|
|
82
|
+
if (!foundTypography && isParentNotRecommended(node)) {
|
|
83
|
+
context.report({
|
|
84
|
+
node,
|
|
85
|
+
messageId: 'textNodeOutsideTypography',
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// Typography found, handle edge cases as documented in
|
|
90
|
+
// https://design.employmenthero.com/web/Components/Typography/#typographytext
|
|
91
|
+
if (foundTypography) {
|
|
92
|
+
switch (tagName) {
|
|
93
|
+
case 'p':
|
|
94
|
+
case '':
|
|
95
|
+
case 'span':
|
|
96
|
+
case 'label': {
|
|
97
|
+
if (level > 1) {
|
|
98
|
+
// Not allowing nested of nested nodes
|
|
99
|
+
context.report({
|
|
100
|
+
node,
|
|
101
|
+
messageId: 'textNodeOutsideTypography',
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
break;
|
|
105
|
+
}
|
|
106
|
+
case 'div': {
|
|
107
|
+
// Allowed cases:
|
|
108
|
+
// 2 level nested with unordered list
|
|
109
|
+
// 2 level nested elements with p
|
|
110
|
+
const parentTagName = getParentTagName(node);
|
|
111
|
+
const grandParentTagName = getParentTagName(node.parent);
|
|
112
|
+
|
|
113
|
+
const isAllowedUnorderedList =
|
|
114
|
+
level === 2 && parentTagName === 'li' && grandParentTagName === 'ul';
|
|
115
|
+
|
|
116
|
+
const isAllowedParagraph = level === 2 && grandParentTagName === 'p';
|
|
117
|
+
|
|
118
|
+
if (!isAllowedParagraph && !isAllowedUnorderedList && level > 1) {
|
|
119
|
+
context.report({
|
|
120
|
+
node,
|
|
121
|
+
messageId: 'textNodeOutsideTypography',
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
break;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
};
|
|
129
|
+
|
|
130
|
+
function containsIntlFormatMessage(expression) {
|
|
131
|
+
if (expression === null || expression === undefined) {
|
|
132
|
+
return false;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
if (
|
|
136
|
+
expression.type === 'CallExpression' &&
|
|
137
|
+
expression.callee.type === 'MemberExpression' &&
|
|
138
|
+
expression.callee.object.name === 'Intl' &&
|
|
139
|
+
expression.callee.property.name === 'formatMessage'
|
|
140
|
+
) {
|
|
141
|
+
return true;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
// Example: {condition1 && Intl.formatMessage({ id: 'someId' })}
|
|
145
|
+
// Also works for multiple logical expressions
|
|
146
|
+
if (expression.type === 'LogicalExpression') {
|
|
147
|
+
return (
|
|
148
|
+
containsIntlFormatMessage(expression.left) ||
|
|
149
|
+
containsIntlFormatMessage(expression.right)
|
|
150
|
+
);
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
if (expression.type === 'ConditionalExpression') {
|
|
154
|
+
return (
|
|
155
|
+
containsIntlFormatMessage(expression.consequent) ||
|
|
156
|
+
containsIntlFormatMessage(expression.alternate)
|
|
157
|
+
);
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
return false;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
module.exports = {
|
|
164
|
+
meta: {
|
|
165
|
+
type: 'problem',
|
|
166
|
+
docs: {
|
|
167
|
+
description: 'Recommend using text inside Typography component.',
|
|
168
|
+
recommended: false,
|
|
169
|
+
},
|
|
170
|
+
schema: [],
|
|
171
|
+
messages: {
|
|
172
|
+
textNodeOutsideTypography:
|
|
173
|
+
'Text nodes should be inside Typography component.',
|
|
174
|
+
},
|
|
175
|
+
},
|
|
176
|
+
create(context) {
|
|
177
|
+
let typographyNames = ['Typography'];
|
|
178
|
+
|
|
179
|
+
return {
|
|
180
|
+
ImportDeclaration(node) {
|
|
181
|
+
if (node.source.value === '@hero-design/react') {
|
|
182
|
+
node.specifiers.forEach((specifier) => {
|
|
183
|
+
if (
|
|
184
|
+
specifier.imported &&
|
|
185
|
+
specifier.imported.name === 'Typography'
|
|
186
|
+
) {
|
|
187
|
+
specifier.local.name !== 'Typography' &&
|
|
188
|
+
typographyNames.push(specifier.local.name);
|
|
189
|
+
}
|
|
190
|
+
});
|
|
191
|
+
}
|
|
192
|
+
},
|
|
193
|
+
VariableDeclarator(node) {
|
|
194
|
+
// Handle local assignments
|
|
195
|
+
if (
|
|
196
|
+
node.init &&
|
|
197
|
+
node.init.type === 'Identifier' &&
|
|
198
|
+
typographyNames.includes(node.init.name)
|
|
199
|
+
) {
|
|
200
|
+
node.id.name !== 'Typography' && typographyNames.push(node.id.name);
|
|
201
|
+
}
|
|
202
|
+
},
|
|
203
|
+
JSXText(node) {
|
|
204
|
+
const trimmedValue = node.value.trim();
|
|
205
|
+
if (trimmedValue) {
|
|
206
|
+
checkNode(node, context, typographyNames);
|
|
207
|
+
}
|
|
208
|
+
},
|
|
209
|
+
JSXExpressionContainer(node) {
|
|
210
|
+
if (containsIntlFormatMessage(node.expression)) {
|
|
211
|
+
checkNode(node, context, typographyNames);
|
|
212
|
+
}
|
|
213
|
+
},
|
|
214
|
+
};
|
|
215
|
+
},
|
|
216
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hero-design/eslint-plugin",
|
|
3
|
-
"version": "9.0
|
|
3
|
+
"version": "9.1.0",
|
|
4
4
|
"description": "Hero Design's eslint plugin",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"eslint",
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
"exports": "./lib/index.js",
|
|
13
13
|
"prettier": "prettier-config-hd",
|
|
14
14
|
"scripts": {
|
|
15
|
-
"lint": "eslint
|
|
15
|
+
"lint": "eslint lib tests",
|
|
16
16
|
"test": "jest --runInBand",
|
|
17
17
|
"test:watch": "jest --runInBand --watch",
|
|
18
18
|
"test:ci": "jest --runInBand --logHeapUsage",
|
|
@@ -22,7 +22,10 @@
|
|
|
22
22
|
"requireindex": "^1.2.0"
|
|
23
23
|
},
|
|
24
24
|
"devDependencies": {
|
|
25
|
-
"eslint": "^
|
|
25
|
+
"@eslint/compat": "^1.1.1",
|
|
26
|
+
"@eslint/eslintrc": "^3.1.0",
|
|
27
|
+
"@eslint/js": "^9.8.0",
|
|
28
|
+
"eslint": "^8.56.0",
|
|
26
29
|
"eslint-plugin-eslint-plugin": "^5.0.0",
|
|
27
30
|
"eslint-plugin-node": "^11.1.0",
|
|
28
31
|
"jest": "^29.2.1",
|
|
@@ -0,0 +1,248 @@
|
|
|
1
|
+
const rule = require('../../../lib/rules/react-no-text-outside-typography');
|
|
2
|
+
const RuleTester = require('eslint').RuleTester;
|
|
3
|
+
|
|
4
|
+
//------------------------------------------------------------------------------
|
|
5
|
+
// Tests
|
|
6
|
+
//------------------------------------------------------------------------------
|
|
7
|
+
|
|
8
|
+
const config = {
|
|
9
|
+
parserOptions: {
|
|
10
|
+
sourceType: 'module',
|
|
11
|
+
ecmaVersion: 6,
|
|
12
|
+
ecmaFeatures: { jsx: true },
|
|
13
|
+
},
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
const ruleTester = new RuleTester();
|
|
17
|
+
ruleTester.run('react-no-text-outside-typography', rule, {
|
|
18
|
+
valid: [
|
|
19
|
+
// Common cases
|
|
20
|
+
{
|
|
21
|
+
code: '<Typography.Text>Content</Typography.Text>',
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
code: '<Typography.Title>Content</Typography.Title>',
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
code: `<Typography.Text>
|
|
28
|
+
Click <a href='..'>here</a>
|
|
29
|
+
</Typography.Text>`,
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
code: `<Typography.Text>
|
|
33
|
+
<Box>Content</Box>
|
|
34
|
+
</Typography.Text>
|
|
35
|
+
`,
|
|
36
|
+
},
|
|
37
|
+
// With Intl.formatMessage and conditions
|
|
38
|
+
{
|
|
39
|
+
code: `<Typography.Text>
|
|
40
|
+
<Box>{Intl.formatMessage({ id: 'someId' })}</Box>
|
|
41
|
+
</Typography.Text>
|
|
42
|
+
`,
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
code: `<Typography.Text>
|
|
46
|
+
<Box>{condition1 && Intl.formatMessage({ id: 'someId' })}</Box>
|
|
47
|
+
</Typography.Text>
|
|
48
|
+
`,
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
code: `<Typography.Text>
|
|
52
|
+
<Box>{condition1 ? Intl.formatMessage({ id: 'someId' }) : null}</Box>
|
|
53
|
+
</Typography.Text>
|
|
54
|
+
`,
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
code: `
|
|
58
|
+
<Typography.Text>
|
|
59
|
+
{Intl.formatMessage({ id: 'someId' })}
|
|
60
|
+
</Typography.Text>`,
|
|
61
|
+
},
|
|
62
|
+
{
|
|
63
|
+
code: `
|
|
64
|
+
<Typography.Text>
|
|
65
|
+
{condition1 && Intl.formatMessage({ id: 'someId' })}
|
|
66
|
+
</Typography.Text>`,
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
code: `
|
|
70
|
+
<Typography.Text>
|
|
71
|
+
{condition1 ? Intl.formatMessage({ id: 'someId' }) : null}
|
|
72
|
+
</Typography.Text>`,
|
|
73
|
+
},
|
|
74
|
+
{
|
|
75
|
+
code: `
|
|
76
|
+
<Typography.Text>
|
|
77
|
+
{condition1 ? Intl.formatMessage({ id: 'someId' }) : Intl.formatMessage({ id: 'someId2' })}
|
|
78
|
+
</Typography.Text>`,
|
|
79
|
+
},
|
|
80
|
+
// Custom namings
|
|
81
|
+
{
|
|
82
|
+
code: `
|
|
83
|
+
import { Typography as HDTypography } from '@hero-design/react';
|
|
84
|
+
<HDTypography.Text>Content</HDTypography.Text>
|
|
85
|
+
`,
|
|
86
|
+
},
|
|
87
|
+
{
|
|
88
|
+
code: `
|
|
89
|
+
import { Typography as HDTypography } from '@hero-design/react';
|
|
90
|
+
const { Text } = HDTypography;
|
|
91
|
+
<Text>Content</Text>
|
|
92
|
+
`,
|
|
93
|
+
},
|
|
94
|
+
{
|
|
95
|
+
code: `
|
|
96
|
+
import { Typography } from '@hero-design/react';
|
|
97
|
+
const { Title } = Typography;
|
|
98
|
+
<Title>Content</Title>
|
|
99
|
+
`,
|
|
100
|
+
},
|
|
101
|
+
{
|
|
102
|
+
code: `
|
|
103
|
+
import { Typography } from '@hero-design/react';
|
|
104
|
+
const { Title: HDTypographyTitle } = Typography;
|
|
105
|
+
<HDTypographyTitle>Content</HDTypographyTitle>
|
|
106
|
+
`,
|
|
107
|
+
},
|
|
108
|
+
{
|
|
109
|
+
code: `
|
|
110
|
+
import { Typography } from '@hero-design/react';
|
|
111
|
+
const Title = Typography.Title;
|
|
112
|
+
<Title>Content</Title>
|
|
113
|
+
`,
|
|
114
|
+
},
|
|
115
|
+
// Exceptions with tagName prop
|
|
116
|
+
{
|
|
117
|
+
code: `
|
|
118
|
+
<Typography.Text tagName='p'>
|
|
119
|
+
<span>Content</span>
|
|
120
|
+
</Typography.Text>
|
|
121
|
+
`,
|
|
122
|
+
},
|
|
123
|
+
{
|
|
124
|
+
code: `
|
|
125
|
+
<Typography.Text tagName='div'>
|
|
126
|
+
<ul>
|
|
127
|
+
<li>Content</li>
|
|
128
|
+
</ul>
|
|
129
|
+
</Typography.Text>
|
|
130
|
+
`,
|
|
131
|
+
},
|
|
132
|
+
{
|
|
133
|
+
code: `
|
|
134
|
+
<Typography.Text tagName='div'>
|
|
135
|
+
<p>
|
|
136
|
+
<a>Content</a>
|
|
137
|
+
</p>
|
|
138
|
+
</Typography.Text>
|
|
139
|
+
`,
|
|
140
|
+
},
|
|
141
|
+
{
|
|
142
|
+
code: `
|
|
143
|
+
<Typography.Text tagName='span'>
|
|
144
|
+
<span>Content</span>
|
|
145
|
+
</Typography.Text>
|
|
146
|
+
`,
|
|
147
|
+
},
|
|
148
|
+
{
|
|
149
|
+
code: `
|
|
150
|
+
<Typography.Text tagName='label'>
|
|
151
|
+
<span>Content</span>
|
|
152
|
+
</Typography.Text>
|
|
153
|
+
`,
|
|
154
|
+
},
|
|
155
|
+
].map((test) => ({ ...test, ...config })),
|
|
156
|
+
invalid: [
|
|
157
|
+
// Common cases
|
|
158
|
+
{
|
|
159
|
+
code: '<div>Content</div>',
|
|
160
|
+
errors: [{ messageId: 'textNodeOutsideTypography' }],
|
|
161
|
+
},
|
|
162
|
+
{
|
|
163
|
+
code: '<p>Content</p>',
|
|
164
|
+
errors: [{ messageId: 'textNodeOutsideTypography' }],
|
|
165
|
+
},
|
|
166
|
+
{
|
|
167
|
+
code: '<h1>Content</h1>',
|
|
168
|
+
errors: [{ messageId: 'textNodeOutsideTypography' }],
|
|
169
|
+
},
|
|
170
|
+
// With Intl.formatMessage and conditions
|
|
171
|
+
{
|
|
172
|
+
code: `
|
|
173
|
+
<div>
|
|
174
|
+
{Intl.formatMessage({ id: 'someId' })}
|
|
175
|
+
</div>`,
|
|
176
|
+
errors: [{ messageId: 'textNodeOutsideTypography' }],
|
|
177
|
+
},
|
|
178
|
+
{
|
|
179
|
+
code: `
|
|
180
|
+
<div>
|
|
181
|
+
{ condition && Intl.formatMessage({ id: 'someId' })}
|
|
182
|
+
</div>`,
|
|
183
|
+
errors: [{ messageId: 'textNodeOutsideTypography' }],
|
|
184
|
+
},
|
|
185
|
+
{
|
|
186
|
+
code: `
|
|
187
|
+
<div>
|
|
188
|
+
{ condition && condition2 && Intl.formatMessage({ id: 'someId' })}
|
|
189
|
+
</div>`,
|
|
190
|
+
errors: [{ messageId: 'textNodeOutsideTypography' }],
|
|
191
|
+
},
|
|
192
|
+
{
|
|
193
|
+
code: `
|
|
194
|
+
<div>
|
|
195
|
+
{ condition && condition2 || condition3 && Intl.formatMessage({ id: 'someId' })}
|
|
196
|
+
</div>`,
|
|
197
|
+
errors: [{ messageId: 'textNodeOutsideTypography' }],
|
|
198
|
+
},
|
|
199
|
+
{
|
|
200
|
+
code: `
|
|
201
|
+
<div>
|
|
202
|
+
{condition1 ? Intl.formatMessage({ id: 'someId' }) : null}
|
|
203
|
+
</div>`,
|
|
204
|
+
errors: [{ messageId: 'textNodeOutsideTypography' }],
|
|
205
|
+
},
|
|
206
|
+
// Exceptions with tagName prop
|
|
207
|
+
{
|
|
208
|
+
code: `
|
|
209
|
+
<Typography.Text tagName='p'>
|
|
210
|
+
<span>
|
|
211
|
+
<span>Content</span>
|
|
212
|
+
</span>
|
|
213
|
+
</Typography.Text>
|
|
214
|
+
`,
|
|
215
|
+
errors: [{ messageId: 'textNodeOutsideTypography' }],
|
|
216
|
+
},
|
|
217
|
+
{
|
|
218
|
+
code: `
|
|
219
|
+
<Typography.Text tagName='div'>
|
|
220
|
+
<span>
|
|
221
|
+
<li>Content</li>
|
|
222
|
+
</span>
|
|
223
|
+
</Typography.Text>
|
|
224
|
+
`,
|
|
225
|
+
errors: [{ messageId: 'textNodeOutsideTypography' }],
|
|
226
|
+
},
|
|
227
|
+
{
|
|
228
|
+
code: `
|
|
229
|
+
<Typography.Text tagName='span'>
|
|
230
|
+
<span>
|
|
231
|
+
<span>Content</span>
|
|
232
|
+
</span>
|
|
233
|
+
</Typography.Text>
|
|
234
|
+
`,
|
|
235
|
+
errors: [{ messageId: 'textNodeOutsideTypography' }],
|
|
236
|
+
},
|
|
237
|
+
{
|
|
238
|
+
code: `
|
|
239
|
+
<Typography.Text tagName='label'>
|
|
240
|
+
<span>
|
|
241
|
+
<span>Content</span>
|
|
242
|
+
</span>
|
|
243
|
+
</Typography.Text>
|
|
244
|
+
`,
|
|
245
|
+
errors: [{ messageId: 'textNodeOutsideTypography' }],
|
|
246
|
+
},
|
|
247
|
+
].map((test) => ({ ...test, ...config })),
|
|
248
|
+
});
|
package/.eslintrc.js
DELETED
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
module.exports = {
|
|
4
|
-
root: true,
|
|
5
|
-
extends: [
|
|
6
|
-
'eslint:recommended',
|
|
7
|
-
'plugin:eslint-plugin/recommended',
|
|
8
|
-
'plugin:node/recommended',
|
|
9
|
-
],
|
|
10
|
-
env: {
|
|
11
|
-
node: true,
|
|
12
|
-
},
|
|
13
|
-
overrides: [
|
|
14
|
-
{
|
|
15
|
-
files: ['tests/**/*.js'],
|
|
16
|
-
env: { jest: true },
|
|
17
|
-
},
|
|
18
|
-
],
|
|
19
|
-
};
|