@dialpad/eslint-plugin-dialtone 1.11.1-next.1 → 1.11.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.
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @fileoverview
|
|
2
|
+
* @fileoverview Combining multiple typography utility categories is discouraged in favor of composed typography utilities
|
|
3
3
|
* @author Nina Repetto
|
|
4
4
|
*/
|
|
5
5
|
'use strict';
|
|
@@ -8,21 +8,30 @@
|
|
|
8
8
|
// Rule Definition
|
|
9
9
|
// ------------------------------------------------------------------------------
|
|
10
10
|
|
|
11
|
+
const typographyCategories = {
|
|
12
|
+
'font-weight': ['d-fw-normal', 'd-fw-medium', 'd-fw-semibold', 'd-fw-bold'],
|
|
13
|
+
'font-size': ['d-fs'], // prefix match
|
|
14
|
+
'line-height': ['d-lh'], // prefix match
|
|
15
|
+
'font-family': ['d-ff-custom', 'd-ff-sans', 'd-ff-mono', 'd-ff-marketing', 'd-ff-unset'],
|
|
16
|
+
};
|
|
17
|
+
|
|
11
18
|
module.exports = {
|
|
12
19
|
meta: {
|
|
13
20
|
type: 'suggestion', // `problem`, `suggestion`, or `layout`
|
|
14
21
|
docs: {
|
|
15
|
-
description: '
|
|
22
|
+
description: 'Combining multiple typography utility categories is discouraged in favor of composed typography utilities',
|
|
16
23
|
recommended: false,
|
|
17
24
|
url: 'https://github.com/dialpad/dialtone/blob/staging/packages/eslint-plugin-dialtone/docs/rules/recommend-typography-style.md', // URL to the documentation page for this rule
|
|
18
25
|
},
|
|
19
26
|
fixable: null, // Or `code` or `whitespace`
|
|
20
27
|
schema: [], // Add a schema if the rule has options
|
|
21
28
|
messages: {
|
|
22
|
-
recommendTypographyStyle: `
|
|
23
|
-
discouraged in favor of composed typography utilities.
|
|
29
|
+
recommendTypographyStyle: `Combining multiple typography utility categories (Font family, Font weight, Font size, Line height) is
|
|
30
|
+
discouraged in favor of composed typography utilities. Check out the available classes here:
|
|
24
31
|
https://dialtone.dialpad.com/design/typography/#api. There can be cases where using these utilities is intentional and valid,
|
|
25
32
|
in which case you can ignore this lint warning.`,
|
|
33
|
+
conflictingTypographyUtilities: `Conflicting typography utilities detected: multiple {{category}} classes found ({{classes}}).
|
|
34
|
+
Only one will be applied. Remove the conflicting classes.`,
|
|
26
35
|
}, // Add messageId and message
|
|
27
36
|
},
|
|
28
37
|
|
|
@@ -33,28 +42,43 @@ module.exports = {
|
|
|
33
42
|
VAttribute (node) {
|
|
34
43
|
if (node.key.name === 'class') {
|
|
35
44
|
const classes = node.value.value.split(' ');
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
if
|
|
45
|
+
|
|
46
|
+
// For each class, determine which category it belongs to and track all matches
|
|
47
|
+
const categoryCounts = {};
|
|
48
|
+
classes.forEach((className) => {
|
|
49
|
+
for (const [category, patterns] of Object.entries(typographyCategories)) {
|
|
50
|
+
if (patterns.some((pattern) => className.startsWith(pattern))) {
|
|
51
|
+
if (!categoryCounts[category]) {
|
|
52
|
+
categoryCounts[category] = [];
|
|
53
|
+
}
|
|
54
|
+
categoryCounts[category].push(className);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
const categoriesFound = Object.keys(categoryCounts);
|
|
60
|
+
|
|
61
|
+
// Report if 2+ different categories are present
|
|
62
|
+
if (categoriesFound.length >= 2) {
|
|
53
63
|
context.report({
|
|
54
64
|
node,
|
|
55
65
|
messageId: 'recommendTypographyStyle',
|
|
56
66
|
});
|
|
57
67
|
}
|
|
68
|
+
|
|
69
|
+
// Report conflicting utilities within the same category
|
|
70
|
+
for (const [category, matchedClasses] of Object.entries(categoryCounts)) {
|
|
71
|
+
if (matchedClasses.length >= 2) {
|
|
72
|
+
context.report({
|
|
73
|
+
node,
|
|
74
|
+
messageId: 'conflictingTypographyUtilities',
|
|
75
|
+
data: {
|
|
76
|
+
category,
|
|
77
|
+
classes: matchedClasses.join(', '),
|
|
78
|
+
},
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
}
|
|
58
82
|
}
|
|
59
83
|
},
|
|
60
84
|
});
|
package/package.json
CHANGED
|
@@ -1,77 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @fileoverview Detects usage of deprecated xxl/xxxl headline sizes which have been renamed to 2xl/3xl.
|
|
3
|
-
* @author Dialtone Team
|
|
4
|
-
*/
|
|
5
|
-
'use strict';
|
|
6
|
-
|
|
7
|
-
// ------------------------------------------------------------------------------
|
|
8
|
-
// Rule Definition
|
|
9
|
-
// ------------------------------------------------------------------------------
|
|
10
|
-
|
|
11
|
-
const SIZE_MAP = {
|
|
12
|
-
xxxl: '3xl',
|
|
13
|
-
xxl: '2xl',
|
|
14
|
-
};
|
|
15
|
-
|
|
16
|
-
module.exports = {
|
|
17
|
-
meta: {
|
|
18
|
-
type: 'suggestion',
|
|
19
|
-
docs: {
|
|
20
|
-
description: 'Headline sizes xxl/xxxl have been renamed to 2xl/3xl.',
|
|
21
|
-
recommended: false,
|
|
22
|
-
url: 'https://github.com/dialpad/dialtone/blob/staging/packages/eslint-plugin-dialtone/docs/rules/deprecated-headline-sizes.md',
|
|
23
|
-
},
|
|
24
|
-
fixable: 'code',
|
|
25
|
-
schema: [],
|
|
26
|
-
messages: {
|
|
27
|
-
deprecatedSize: 'Headline size "{{oldSize}}" has been renamed to "{{newSize}}". Update size="{{oldSize}}" to size="{{newSize}}".',
|
|
28
|
-
deprecatedClass: 'CSS class "{{oldClass}}" has been renamed to "{{newClass}}". Update to use the new class name.',
|
|
29
|
-
},
|
|
30
|
-
},
|
|
31
|
-
|
|
32
|
-
create(context) {
|
|
33
|
-
const sourceCode = context.sourceCode ?? context.getSourceCode();
|
|
34
|
-
return sourceCode.parserServices.defineTemplateBodyVisitor({
|
|
35
|
-
VAttribute(node) {
|
|
36
|
-
// Check size prop (e.g., size="xxl" or size="xxxl")
|
|
37
|
-
if (node.key.name === 'size' && node.value && node.value.value) {
|
|
38
|
-
const sizeValue = node.value.value;
|
|
39
|
-
if (SIZE_MAP[sizeValue]) {
|
|
40
|
-
context.report({
|
|
41
|
-
node,
|
|
42
|
-
messageId: 'deprecatedSize',
|
|
43
|
-
data: {
|
|
44
|
-
oldSize: sizeValue,
|
|
45
|
-
newSize: SIZE_MAP[sizeValue],
|
|
46
|
-
},
|
|
47
|
-
fix(fixer) {
|
|
48
|
-
return fixer.replaceText(node.value, `"${SIZE_MAP[sizeValue]}"`);
|
|
49
|
-
},
|
|
50
|
-
});
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
// Check class attributes for deprecated d-text-headline--xxl/xxxl classes
|
|
55
|
-
// Note: We only flag d-text-headline-- (current system), NOT d-headline-- (legacy system)
|
|
56
|
-
if (node.key.name === 'class' && node.value && node.value.value) {
|
|
57
|
-
const classValue = node.value.value;
|
|
58
|
-
// Match d-text-headline--xxl or d-text-headline--xxxl (but NOT d-headline--xxl)
|
|
59
|
-
const match = classValue.match(/\bd-text-headline--(xxx?l)\b/);
|
|
60
|
-
if (match && SIZE_MAP[match[1]]) {
|
|
61
|
-
const oldClass = `d-text-headline--${match[1]}`;
|
|
62
|
-
const newClass = `d-text-headline--${SIZE_MAP[match[1]]}`;
|
|
63
|
-
context.report({
|
|
64
|
-
node,
|
|
65
|
-
messageId: 'deprecatedClass',
|
|
66
|
-
data: { oldClass, newClass },
|
|
67
|
-
fix(fixer) {
|
|
68
|
-
const newValue = classValue.replace(oldClass, newClass);
|
|
69
|
-
return fixer.replaceText(node.value, `"${newValue}"`);
|
|
70
|
-
},
|
|
71
|
-
});
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
},
|
|
75
|
-
});
|
|
76
|
-
},
|
|
77
|
-
};
|