@blumintinc/eslint-plugin-blumint 1.20.34 → 1.20.36
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/lib/index.js
CHANGED
|
@@ -1,7 +1 @@
|
|
|
1
|
-
|
|
2
|
-
{
|
|
3
|
-
autofix?: boolean;
|
|
4
|
-
}
|
|
5
|
-
];
|
|
6
|
-
export declare const noMarginProperties: import("@typescript-eslint/utils/dist/ts-eslint/Rule").RuleModule<"noMarginProperties", Options, import("@typescript-eslint/utils/dist/ts-eslint/Rule").RuleListener>;
|
|
7
|
-
export {};
|
|
1
|
+
export declare const noMarginProperties: import("@typescript-eslint/utils/dist/ts-eslint/Rule").RuleModule<"noMarginProperties", [], import("@typescript-eslint/utils/dist/ts-eslint/Rule").RuleListener>;
|
|
@@ -42,27 +42,14 @@ exports.noMarginProperties = (0, createRule_1.createRule)({
|
|
|
42
42
|
description: 'Prevent margin properties (margin, marginLeft, marginRight, marginTop, marginBottom, mx, my, etc.) in MUI styling because margins fight container-controlled spacing, double gutters, and misaligned breakpoints; keep spacing centralized with padding, gap, or spacing props instead.',
|
|
43
43
|
recommended: 'error',
|
|
44
44
|
},
|
|
45
|
-
schema: [
|
|
46
|
-
{
|
|
47
|
-
type: 'object',
|
|
48
|
-
properties: {
|
|
49
|
-
autofix: {
|
|
50
|
-
type: 'boolean',
|
|
51
|
-
default: false,
|
|
52
|
-
},
|
|
53
|
-
},
|
|
54
|
-
additionalProperties: false,
|
|
55
|
-
},
|
|
56
|
-
],
|
|
45
|
+
schema: [],
|
|
57
46
|
messages: {
|
|
58
47
|
noMarginProperties: 'Margin property "{{property}}" in MUI styling fights container-controlled spacing (Stack/Grid spacing, gap, responsive gutters) and produces double gutters, misalignment, and overflow as layouts shift. Keep spacing inside the component with padding or let the parent handle separation via gap/spacing so layout remains predictable.',
|
|
59
48
|
},
|
|
60
49
|
},
|
|
61
|
-
defaultOptions: [
|
|
50
|
+
defaultOptions: [],
|
|
62
51
|
create(context) {
|
|
63
52
|
const seenNodes = new WeakSet();
|
|
64
|
-
// Note: autofix option is available but not currently implemented
|
|
65
|
-
// Future implementation can use: const { autofix = false } = _options;
|
|
66
53
|
function checkProperty(propertyName) {
|
|
67
54
|
const normalizedName = normalizePropertyName(propertyName);
|
|
68
55
|
return MARGIN_PROPERTIES.has(normalizedName);
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
const utils_1 = require("@typescript-eslint/utils");
|
|
3
3
|
const path_1 = require("path");
|
|
4
|
+
const ASTHelpers_1 = require("../utils/ASTHelpers");
|
|
4
5
|
const createRule_1 = require("../utils/createRule");
|
|
5
6
|
const DEFAULT_COMPONENT_PATH = 'src/components/image/ImageOptimized';
|
|
6
7
|
/** The JSX name the fixer writes, and the named export it comes from. */
|
|
@@ -82,6 +83,24 @@ const isBoundAsValue = (scope, name) => {
|
|
|
82
83
|
variable.defs.length > 0 &&
|
|
83
84
|
variable.defs.some((definition) => !isTypeOnlyImport(definition)));
|
|
84
85
|
};
|
|
86
|
+
/**
|
|
87
|
+
* Whether the name the fixer is about to emit still resolves, at the report
|
|
88
|
+
* site, to a declaration in the file's module scope — where the component's
|
|
89
|
+
* import, and any module-scope stand-in such as `const ImageOptimized =
|
|
90
|
+
* dynamic(...)`, live. A binding introduced by an enclosing inner scope (a
|
|
91
|
+
* local, a parameter, a block-scoped const) captures the emitted element
|
|
92
|
+
* instead: the name is bound, so no reference is stranded and TypeScript
|
|
93
|
+
* accepts the element, yet the fix silently renders that local value rather
|
|
94
|
+
* than the shared wrapper.
|
|
95
|
+
*/
|
|
96
|
+
const resolvesToModuleBinding = (scope, name) => {
|
|
97
|
+
const variable = ASTHelpers_1.ASTHelpers.findVariableInScope(scope, name);
|
|
98
|
+
// A variable with no definition is an ambient global, which is no component
|
|
99
|
+
// and cannot be the import the emitted element is meant to reach.
|
|
100
|
+
return (!!variable &&
|
|
101
|
+
variable.defs.length > 0 &&
|
|
102
|
+
variable.scope.block.type === utils_1.AST_NODE_TYPES.Program);
|
|
103
|
+
};
|
|
85
104
|
/**
|
|
86
105
|
* Local name the component is imported under, when it is aliased away from
|
|
87
106
|
* `ImageOptimized`. Reusing the alias keeps the fix bound to a real import
|
|
@@ -158,7 +177,7 @@ module.exports = (0, createRule_1.createRule)({
|
|
|
158
177
|
isInsideComponentMock(node, componentModule)) {
|
|
159
178
|
return;
|
|
160
179
|
}
|
|
161
|
-
const scope =
|
|
180
|
+
const scope = ASTHelpers_1.ASTHelpers.getScope(context, node);
|
|
162
181
|
const localName = isBoundAsValue(scope, COMPONENT_NAME)
|
|
163
182
|
? COMPONENT_NAME
|
|
164
183
|
: aliasedLocalName(sourceCode.ast, componentModule);
|
|
@@ -176,6 +195,12 @@ module.exports = (0, createRule_1.createRule)({
|
|
|
176
195
|
if (!localName) {
|
|
177
196
|
return null;
|
|
178
197
|
}
|
|
198
|
+
// A shadow of that name over the report site would make the swap
|
|
199
|
+
// render the shadow's value; declining leaves the report for the
|
|
200
|
+
// author to resolve the shadow by hand.
|
|
201
|
+
if (!resolvesToModuleBinding(scope, localName)) {
|
|
202
|
+
return null;
|
|
203
|
+
}
|
|
179
204
|
const attributes = node.openingElement.attributes
|
|
180
205
|
.map((attribute) => sourceCode.getText(attribute))
|
|
181
206
|
.join(' ');
|
package/package.json
CHANGED
package/release-manifest.json
CHANGED
|
@@ -1,4 +1,32 @@
|
|
|
1
1
|
[
|
|
2
|
+
{
|
|
3
|
+
"version": "1.20.36",
|
|
4
|
+
"date": "2026-07-30T17:05:52.383Z",
|
|
5
|
+
"rules": [
|
|
6
|
+
{
|
|
7
|
+
"name": "no-margin-properties",
|
|
8
|
+
"changeType": "fix",
|
|
9
|
+
"issues": [
|
|
10
|
+
1460
|
|
11
|
+
],
|
|
12
|
+
"summary": "remove the inert autofix option (closes #1460)"
|
|
13
|
+
}
|
|
14
|
+
]
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
"version": "1.20.35",
|
|
18
|
+
"date": "2026-07-30T16:38:05.368Z",
|
|
19
|
+
"rules": [
|
|
20
|
+
{
|
|
21
|
+
"name": "require-image-optimized",
|
|
22
|
+
"changeType": "fix",
|
|
23
|
+
"issues": [
|
|
24
|
+
1457
|
|
25
|
+
],
|
|
26
|
+
"summary": "decline the autofix when a shadow captures the reused import alias (closes #1457)"
|
|
27
|
+
}
|
|
28
|
+
]
|
|
29
|
+
},
|
|
2
30
|
{
|
|
3
31
|
"version": "1.20.34",
|
|
4
32
|
"date": "2026-07-30T16:15:43.598Z",
|