@drskillissue/ganko 0.2.71 → 0.2.72
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/README.md +1 -1
- package/dist/{chunk-SVX3WRFV.js → chunk-MJKIL7DJ.js} +341 -264
- package/dist/chunk-MJKIL7DJ.js.map +1 -0
- package/dist/{chunk-5OEDGKHL.js → chunk-NFDA6LAI.js} +17 -15
- package/dist/chunk-NFDA6LAI.js.map +1 -0
- package/dist/eslint-plugin.cjs +322 -258
- package/dist/eslint-plugin.cjs.map +1 -1
- package/dist/eslint-plugin.js +1 -1
- package/dist/index.cjs +356 -277
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +2 -2
- package/dist/rules-manifest.cjs +16 -14
- package/dist/rules-manifest.cjs.map +1 -1
- package/dist/rules-manifest.js +1 -1
- package/package.json +1 -1
- package/dist/chunk-5OEDGKHL.js.map +0 -1
- package/dist/chunk-SVX3WRFV.js.map +0 -1
package/dist/eslint-plugin.cjs
CHANGED
|
@@ -29538,148 +29538,8 @@ function checkParagraphSpacing(graph, emit, policy, name) {
|
|
|
29538
29538
|
}
|
|
29539
29539
|
}
|
|
29540
29540
|
|
|
29541
|
-
// src/css/rules/a11y/css-policy-touch-target.ts
|
|
29542
|
-
var messages125 = {
|
|
29543
|
-
heightTooSmall: "`{{property}}` of `{{value}}` ({{resolved}}px) is below the minimum `{{min}}px` for `{{element}}` elements in policy `{{policy}}`.",
|
|
29544
|
-
widthTooSmall: "`{{property}}` of `{{value}}` ({{resolved}}px) is below the minimum `{{min}}px` for `{{element}}` elements in policy `{{policy}}`.",
|
|
29545
|
-
paddingTooSmall: "Horizontal padding `{{value}}` ({{resolved}}px) is below the minimum `{{min}}px` for `{{element}}` elements in policy `{{policy}}`."
|
|
29546
|
-
};
|
|
29547
|
-
function classifyRule(rule) {
|
|
29548
|
-
if (rule.elementKinds.has("button")) return "button";
|
|
29549
|
-
if (rule.elementKinds.has("input")) return "input";
|
|
29550
|
-
return null;
|
|
29551
|
-
}
|
|
29552
|
-
var HEIGHT_PROPERTIES = /* @__PURE__ */ new Set(["height", "min-height"]);
|
|
29553
|
-
var WIDTH_PROPERTIES = /* @__PURE__ */ new Set(["width", "min-width"]);
|
|
29554
|
-
var HPADDING_PROPERTIES = /* @__PURE__ */ new Set(["padding-left", "padding-right", "padding-inline", "padding-inline-start", "padding-inline-end"]);
|
|
29555
|
-
var cssPolicyTouchTarget = defineCSSRule({
|
|
29556
|
-
id: "css-policy-touch-target",
|
|
29557
|
-
severity: "warn",
|
|
29558
|
-
messages: messages125,
|
|
29559
|
-
meta: {
|
|
29560
|
-
description: "Enforce minimum interactive element sizes per accessibility policy.",
|
|
29561
|
-
fixable: false,
|
|
29562
|
-
category: "css-a11y"
|
|
29563
|
-
},
|
|
29564
|
-
options: {},
|
|
29565
|
-
check(graph, emit) {
|
|
29566
|
-
const policy = getActivePolicy();
|
|
29567
|
-
if (policy === null) return;
|
|
29568
|
-
const name = getActivePolicyName() ?? "";
|
|
29569
|
-
const decls = graph.declarationsForProperties(
|
|
29570
|
-
"height",
|
|
29571
|
-
"min-height",
|
|
29572
|
-
"width",
|
|
29573
|
-
"min-width",
|
|
29574
|
-
"padding-left",
|
|
29575
|
-
"padding-right",
|
|
29576
|
-
"padding-inline",
|
|
29577
|
-
"padding-inline-start",
|
|
29578
|
-
"padding-inline-end"
|
|
29579
|
-
);
|
|
29580
|
-
for (let i = 0; i < decls.length; i++) {
|
|
29581
|
-
const d = decls[i];
|
|
29582
|
-
if (!d) continue;
|
|
29583
|
-
if (!d.rule) continue;
|
|
29584
|
-
const prop = d.property.toLowerCase();
|
|
29585
|
-
const kind = classifyRule(d.rule);
|
|
29586
|
-
if (!kind) continue;
|
|
29587
|
-
if (isVisuallyHiddenInput(d.rule)) continue;
|
|
29588
|
-
const px = parsePxValue(d.value);
|
|
29589
|
-
if (px === null) continue;
|
|
29590
|
-
if (HEIGHT_PROPERTIES.has(prop)) {
|
|
29591
|
-
const min = kind === "button" ? policy.minButtonHeight : policy.minInputHeight;
|
|
29592
|
-
if (px >= min) continue;
|
|
29593
|
-
emitCSSDiagnostic(
|
|
29594
|
-
emit,
|
|
29595
|
-
d.file.path,
|
|
29596
|
-
d.startLine,
|
|
29597
|
-
d.startColumn,
|
|
29598
|
-
cssPolicyTouchTarget,
|
|
29599
|
-
"heightTooSmall",
|
|
29600
|
-
resolveMessage(messages125.heightTooSmall, {
|
|
29601
|
-
property: d.property,
|
|
29602
|
-
value: d.value.trim(),
|
|
29603
|
-
resolved: String(Math.round(px * 100) / 100),
|
|
29604
|
-
min: String(min),
|
|
29605
|
-
element: kind,
|
|
29606
|
-
policy: name
|
|
29607
|
-
})
|
|
29608
|
-
);
|
|
29609
|
-
continue;
|
|
29610
|
-
}
|
|
29611
|
-
if (WIDTH_PROPERTIES.has(prop)) {
|
|
29612
|
-
const min = kind === "button" ? policy.minButtonWidth : policy.minTouchTarget;
|
|
29613
|
-
if (px >= min) continue;
|
|
29614
|
-
emitCSSDiagnostic(
|
|
29615
|
-
emit,
|
|
29616
|
-
d.file.path,
|
|
29617
|
-
d.startLine,
|
|
29618
|
-
d.startColumn,
|
|
29619
|
-
cssPolicyTouchTarget,
|
|
29620
|
-
"widthTooSmall",
|
|
29621
|
-
resolveMessage(messages125.widthTooSmall, {
|
|
29622
|
-
property: d.property,
|
|
29623
|
-
value: d.value.trim(),
|
|
29624
|
-
resolved: String(Math.round(px * 100) / 100),
|
|
29625
|
-
min: String(min),
|
|
29626
|
-
element: kind,
|
|
29627
|
-
policy: name
|
|
29628
|
-
})
|
|
29629
|
-
);
|
|
29630
|
-
continue;
|
|
29631
|
-
}
|
|
29632
|
-
if (kind === "button" && HPADDING_PROPERTIES.has(prop)) {
|
|
29633
|
-
if (px >= policy.minButtonHorizontalPadding) continue;
|
|
29634
|
-
emitCSSDiagnostic(
|
|
29635
|
-
emit,
|
|
29636
|
-
d.file.path,
|
|
29637
|
-
d.startLine,
|
|
29638
|
-
d.startColumn,
|
|
29639
|
-
cssPolicyTouchTarget,
|
|
29640
|
-
"paddingTooSmall",
|
|
29641
|
-
resolveMessage(messages125.paddingTooSmall, {
|
|
29642
|
-
value: d.value.trim(),
|
|
29643
|
-
resolved: String(Math.round(px * 100) / 100),
|
|
29644
|
-
min: String(policy.minButtonHorizontalPadding),
|
|
29645
|
-
element: kind,
|
|
29646
|
-
policy: name
|
|
29647
|
-
})
|
|
29648
|
-
);
|
|
29649
|
-
}
|
|
29650
|
-
}
|
|
29651
|
-
}
|
|
29652
|
-
});
|
|
29653
|
-
function isVisuallyHiddenInput(rule) {
|
|
29654
|
-
if (!hasPositionAbsoluteOrFixed(rule)) return false;
|
|
29655
|
-
if (!hasOpacityZero(rule)) return false;
|
|
29656
|
-
return true;
|
|
29657
|
-
}
|
|
29658
|
-
function hasPositionAbsoluteOrFixed(rule) {
|
|
29659
|
-
const positionDecls = rule.declarationIndex.get("position");
|
|
29660
|
-
if (!positionDecls || positionDecls.length === 0) return false;
|
|
29661
|
-
for (let i = 0; i < positionDecls.length; i++) {
|
|
29662
|
-
const decl = positionDecls[i];
|
|
29663
|
-
if (!decl) continue;
|
|
29664
|
-
const v = decl.value.trim().toLowerCase();
|
|
29665
|
-
if (v === "absolute" || v === "fixed") return true;
|
|
29666
|
-
}
|
|
29667
|
-
return false;
|
|
29668
|
-
}
|
|
29669
|
-
function hasOpacityZero(rule) {
|
|
29670
|
-
const opacityDecls = rule.declarationIndex.get("opacity");
|
|
29671
|
-
if (!opacityDecls || opacityDecls.length === 0) return false;
|
|
29672
|
-
for (let i = 0; i < opacityDecls.length; i++) {
|
|
29673
|
-
const decl = opacityDecls[i];
|
|
29674
|
-
if (!decl) continue;
|
|
29675
|
-
const v = decl.value.trim();
|
|
29676
|
-
if (v === "0") return true;
|
|
29677
|
-
}
|
|
29678
|
-
return false;
|
|
29679
|
-
}
|
|
29680
|
-
|
|
29681
29541
|
// src/css/rules/a11y/css-policy-typography.ts
|
|
29682
|
-
var
|
|
29542
|
+
var messages125 = {
|
|
29683
29543
|
fontTooSmall: "Font size `{{value}}` ({{resolved}}px) is below the `{{context}}` minimum of `{{min}}px` for policy `{{policy}}`.",
|
|
29684
29544
|
lineHeightTooSmall: "Line height `{{value}}` is below the `{{context}}` minimum of `{{min}}` for policy `{{policy}}`."
|
|
29685
29545
|
};
|
|
@@ -29715,7 +29575,7 @@ function resolveLineHeightContext(d, p) {
|
|
|
29715
29575
|
var cssPolicyTypography = defineCSSRule({
|
|
29716
29576
|
id: "css-policy-typography",
|
|
29717
29577
|
severity: "warn",
|
|
29718
|
-
messages:
|
|
29578
|
+
messages: messages125,
|
|
29719
29579
|
meta: {
|
|
29720
29580
|
description: "Enforce minimum font sizes and line heights per accessibility policy.",
|
|
29721
29581
|
fixable: false,
|
|
@@ -29742,7 +29602,7 @@ var cssPolicyTypography = defineCSSRule({
|
|
|
29742
29602
|
d.startColumn,
|
|
29743
29603
|
cssPolicyTypography,
|
|
29744
29604
|
"fontTooSmall",
|
|
29745
|
-
resolveMessage(
|
|
29605
|
+
resolveMessage(messages125.fontTooSmall, {
|
|
29746
29606
|
value: d.value.trim(),
|
|
29747
29607
|
resolved: String(Math.round(px * 100) / 100),
|
|
29748
29608
|
context,
|
|
@@ -29769,7 +29629,7 @@ var cssPolicyTypography = defineCSSRule({
|
|
|
29769
29629
|
d.startColumn,
|
|
29770
29630
|
cssPolicyTypography,
|
|
29771
29631
|
"lineHeightTooSmall",
|
|
29772
|
-
resolveMessage(
|
|
29632
|
+
resolveMessage(messages125.lineHeightTooSmall, {
|
|
29773
29633
|
value: d.value.trim(),
|
|
29774
29634
|
context,
|
|
29775
29635
|
min: String(min),
|
|
@@ -29787,7 +29647,7 @@ var ZERO_S = /(^|\s|,)0s($|\s|,)/;
|
|
|
29787
29647
|
var TIME_VALUE_G = /([0-9]*\.?[0-9]+)(ms|s)/g;
|
|
29788
29648
|
var AMPERSAND_G = /&/g;
|
|
29789
29649
|
var WHITESPACE_G = /\s+/g;
|
|
29790
|
-
var
|
|
29650
|
+
var messages126 = {
|
|
29791
29651
|
missingReducedMotion: "Animated selector `{{selector}}` lacks prefers-reduced-motion override."
|
|
29792
29652
|
};
|
|
29793
29653
|
function isAnimationDecl(p) {
|
|
@@ -29891,7 +29751,7 @@ function normalizeSelector2(s) {
|
|
|
29891
29751
|
var cssRequireReducedMotionOverride = defineCSSRule({
|
|
29892
29752
|
id: "css-require-reduced-motion-override",
|
|
29893
29753
|
severity: "warn",
|
|
29894
|
-
messages:
|
|
29754
|
+
messages: messages126,
|
|
29895
29755
|
meta: {
|
|
29896
29756
|
description: "Require reduced-motion override for animated selectors.",
|
|
29897
29757
|
fixable: false,
|
|
@@ -29954,20 +29814,20 @@ var cssRequireReducedMotionOverride = defineCSSRule({
|
|
|
29954
29814
|
d.startColumn,
|
|
29955
29815
|
cssRequireReducedMotionOverride,
|
|
29956
29816
|
"missingReducedMotion",
|
|
29957
|
-
resolveMessage(
|
|
29817
|
+
resolveMessage(messages126.missingReducedMotion, { selector: r.selectorText })
|
|
29958
29818
|
);
|
|
29959
29819
|
}
|
|
29960
29820
|
}
|
|
29961
29821
|
});
|
|
29962
29822
|
|
|
29963
29823
|
// src/css/rules/structure/css-no-empty-rule.ts
|
|
29964
|
-
var
|
|
29824
|
+
var messages127 = {
|
|
29965
29825
|
emptyRule: "Empty rule `{{selector}}` should be removed."
|
|
29966
29826
|
};
|
|
29967
29827
|
var cssNoEmptyRule = defineCSSRule({
|
|
29968
29828
|
id: "css-no-empty-rule",
|
|
29969
29829
|
severity: "warn",
|
|
29970
|
-
messages:
|
|
29830
|
+
messages: messages127,
|
|
29971
29831
|
meta: {
|
|
29972
29832
|
description: "Disallow empty CSS rules.",
|
|
29973
29833
|
fixable: false,
|
|
@@ -29985,20 +29845,20 @@ var cssNoEmptyRule = defineCSSRule({
|
|
|
29985
29845
|
rule.startColumn,
|
|
29986
29846
|
cssNoEmptyRule,
|
|
29987
29847
|
"emptyRule",
|
|
29988
|
-
resolveMessage(
|
|
29848
|
+
resolveMessage(messages127.emptyRule, { selector: rule.selectorText })
|
|
29989
29849
|
);
|
|
29990
29850
|
}
|
|
29991
29851
|
}
|
|
29992
29852
|
});
|
|
29993
29853
|
|
|
29994
29854
|
// src/css/rules/structure/css-no-unknown-container-name.ts
|
|
29995
|
-
var
|
|
29855
|
+
var messages128 = {
|
|
29996
29856
|
unknownContainer: "Unknown container name `{{name}}` in @container query."
|
|
29997
29857
|
};
|
|
29998
29858
|
var cssNoUnknownContainerName = defineCSSRule({
|
|
29999
29859
|
id: "css-no-unknown-container-name",
|
|
30000
29860
|
severity: "error",
|
|
30001
|
-
messages:
|
|
29861
|
+
messages: messages128,
|
|
30002
29862
|
meta: {
|
|
30003
29863
|
description: "Disallow unknown named containers in @container queries.",
|
|
30004
29864
|
fixable: false,
|
|
@@ -30018,20 +29878,20 @@ var cssNoUnknownContainerName = defineCSSRule({
|
|
|
30018
29878
|
1,
|
|
30019
29879
|
cssNoUnknownContainerName,
|
|
30020
29880
|
"unknownContainer",
|
|
30021
|
-
resolveMessage(
|
|
29881
|
+
resolveMessage(messages128.unknownContainer, { name })
|
|
30022
29882
|
);
|
|
30023
29883
|
}
|
|
30024
29884
|
}
|
|
30025
29885
|
});
|
|
30026
29886
|
|
|
30027
29887
|
// src/css/rules/structure/css-no-unused-container-name.ts
|
|
30028
|
-
var
|
|
29888
|
+
var messages129 = {
|
|
30029
29889
|
unusedContainer: "Container name `{{name}}` is declared but never queried."
|
|
30030
29890
|
};
|
|
30031
29891
|
var cssNoUnusedContainerName = defineCSSRule({
|
|
30032
29892
|
id: "css-no-unused-container-name",
|
|
30033
29893
|
severity: "warn",
|
|
30034
|
-
messages:
|
|
29894
|
+
messages: messages129,
|
|
30035
29895
|
meta: {
|
|
30036
29896
|
description: "Disallow unused named containers.",
|
|
30037
29897
|
fixable: false,
|
|
@@ -30054,7 +29914,7 @@ var cssNoUnusedContainerName = defineCSSRule({
|
|
|
30054
29914
|
d.startColumn,
|
|
30055
29915
|
cssNoUnusedContainerName,
|
|
30056
29916
|
"unusedContainer",
|
|
30057
|
-
resolveMessage(
|
|
29917
|
+
resolveMessage(messages129.unusedContainer, { name })
|
|
30058
29918
|
);
|
|
30059
29919
|
}
|
|
30060
29920
|
}
|
|
@@ -30062,13 +29922,13 @@ var cssNoUnusedContainerName = defineCSSRule({
|
|
|
30062
29922
|
});
|
|
30063
29923
|
|
|
30064
29924
|
// src/css/rules/structure/layer-requirement-for-component-rules.ts
|
|
30065
|
-
var
|
|
29925
|
+
var messages130 = {
|
|
30066
29926
|
missingLayer: "Rule `{{selector}}` is not inside any @layer block while this file uses @layer. Place component rules inside an explicit layer."
|
|
30067
29927
|
};
|
|
30068
29928
|
var layerRequirementForComponentRules = defineCSSRule({
|
|
30069
29929
|
id: "layer-requirement-for-component-rules",
|
|
30070
29930
|
severity: "warn",
|
|
30071
|
-
messages:
|
|
29931
|
+
messages: messages130,
|
|
30072
29932
|
meta: {
|
|
30073
29933
|
description: "Require style rules to be inside @layer when the file defines layers.",
|
|
30074
29934
|
fixable: false,
|
|
@@ -30087,7 +29947,7 @@ var layerRequirementForComponentRules = defineCSSRule({
|
|
|
30087
29947
|
rule.startColumn,
|
|
30088
29948
|
layerRequirementForComponentRules,
|
|
30089
29949
|
"missingLayer",
|
|
30090
|
-
resolveMessage(
|
|
29950
|
+
resolveMessage(messages130.missingLayer, {
|
|
30091
29951
|
selector: rule.selectorText
|
|
30092
29952
|
})
|
|
30093
29953
|
);
|
|
@@ -30127,7 +29987,6 @@ var rules2 = [
|
|
|
30127
29987
|
selectorMaxAttributeAndUniversal,
|
|
30128
29988
|
selectorMaxSpecificity,
|
|
30129
29989
|
cssPolicyTypography,
|
|
30130
|
-
cssPolicyTouchTarget,
|
|
30131
29990
|
cssPolicySpacing,
|
|
30132
29991
|
cssPolicyContrast
|
|
30133
29992
|
];
|
|
@@ -38964,13 +38823,13 @@ function emitLayoutDiagnostic(layout, node, emit, ruleId, messageId, template, s
|
|
|
38964
38823
|
}
|
|
38965
38824
|
|
|
38966
38825
|
// src/cross-file/rules/undefined-css-class.ts
|
|
38967
|
-
var
|
|
38826
|
+
var messages131 = {
|
|
38968
38827
|
undefinedClass: "CSS class '{{className}}' is not defined in project CSS files"
|
|
38969
38828
|
};
|
|
38970
38829
|
var jsxNoUndefinedCssClass = defineCrossRule({
|
|
38971
38830
|
id: "jsx-no-undefined-css-class",
|
|
38972
38831
|
severity: "error",
|
|
38973
|
-
messages:
|
|
38832
|
+
messages: messages131,
|
|
38974
38833
|
meta: {
|
|
38975
38834
|
description: "Detect undefined CSS class names in JSX",
|
|
38976
38835
|
fixable: false,
|
|
@@ -38989,7 +38848,7 @@ var jsxNoUndefinedCssClass = defineCrossRule({
|
|
|
38989
38848
|
ref.solid.sourceFile,
|
|
38990
38849
|
jsxNoUndefinedCssClass.id,
|
|
38991
38850
|
"undefinedClass",
|
|
38992
|
-
resolveMessage(
|
|
38851
|
+
resolveMessage(messages131.undefinedClass, { className: item.className }),
|
|
38993
38852
|
"error"
|
|
38994
38853
|
));
|
|
38995
38854
|
}
|
|
@@ -38997,13 +38856,13 @@ var jsxNoUndefinedCssClass = defineCrossRule({
|
|
|
38997
38856
|
});
|
|
38998
38857
|
|
|
38999
38858
|
// src/cross-file/rules/unreferenced-css-class.ts
|
|
39000
|
-
var
|
|
38859
|
+
var messages132 = {
|
|
39001
38860
|
unreferencedClass: "CSS class '{{className}}' is defined but not referenced by static JSX class attributes"
|
|
39002
38861
|
};
|
|
39003
38862
|
var cssNoUnreferencedComponentClass = defineCrossRule({
|
|
39004
38863
|
id: "css-no-unreferenced-component-class",
|
|
39005
38864
|
severity: "warn",
|
|
39006
|
-
messages:
|
|
38865
|
+
messages: messages132,
|
|
39007
38866
|
meta: {
|
|
39008
38867
|
description: "Detect CSS classes that are never referenced by static JSX class attributes.",
|
|
39009
38868
|
fixable: false,
|
|
@@ -39027,7 +38886,7 @@ var cssNoUnreferencedComponentClass = defineCrossRule({
|
|
|
39027
38886
|
},
|
|
39028
38887
|
cssNoUnreferencedComponentClass.id,
|
|
39029
38888
|
"unreferencedClass",
|
|
39030
|
-
resolveMessage(
|
|
38889
|
+
resolveMessage(messages132.unreferencedClass, { className }),
|
|
39031
38890
|
"warn"
|
|
39032
38891
|
)
|
|
39033
38892
|
);
|
|
@@ -39036,13 +38895,13 @@ var cssNoUnreferencedComponentClass = defineCrossRule({
|
|
|
39036
38895
|
});
|
|
39037
38896
|
|
|
39038
38897
|
// src/cross-file/rules/jsx-no-duplicate-class-token-class-classlist.ts
|
|
39039
|
-
var
|
|
38898
|
+
var messages133 = {
|
|
39040
38899
|
duplicateClassToken: "Class token `{{name}}` appears in both class and classList."
|
|
39041
38900
|
};
|
|
39042
38901
|
var jsxNoDuplicateClassTokenClassClasslist = defineCrossRule({
|
|
39043
38902
|
id: "jsx-no-duplicate-class-token-class-classlist",
|
|
39044
38903
|
severity: "warn",
|
|
39045
|
-
messages:
|
|
38904
|
+
messages: messages133,
|
|
39046
38905
|
meta: {
|
|
39047
38906
|
description: "Disallow duplicate class tokens between class and classList on the same JSX element.",
|
|
39048
38907
|
fixable: false,
|
|
@@ -39084,7 +38943,7 @@ var jsxNoDuplicateClassTokenClassClasslist = defineCrossRule({
|
|
|
39084
38943
|
solid.sourceFile,
|
|
39085
38944
|
jsxNoDuplicateClassTokenClassClasslist.id,
|
|
39086
38945
|
"duplicateClassToken",
|
|
39087
|
-
resolveMessage(
|
|
38946
|
+
resolveMessage(messages133.duplicateClassToken, { name: token }),
|
|
39088
38947
|
"warn"
|
|
39089
38948
|
));
|
|
39090
38949
|
}
|
|
@@ -39095,13 +38954,13 @@ var jsxNoDuplicateClassTokenClassClasslist = defineCrossRule({
|
|
|
39095
38954
|
|
|
39096
38955
|
// src/cross-file/rules/jsx-classlist-static-keys.ts
|
|
39097
38956
|
var import_typescript128 = __toESM(require("typescript"), 1);
|
|
39098
|
-
var
|
|
38957
|
+
var messages134 = {
|
|
39099
38958
|
nonStaticKey: "classList key must be statically known for reliable class mapping."
|
|
39100
38959
|
};
|
|
39101
38960
|
var jsxClasslistStaticKeys = defineCrossRule({
|
|
39102
38961
|
id: "jsx-classlist-static-keys",
|
|
39103
38962
|
severity: "error",
|
|
39104
|
-
messages:
|
|
38963
|
+
messages: messages134,
|
|
39105
38964
|
meta: {
|
|
39106
38965
|
description: "Require classList keys to be static and non-computed.",
|
|
39107
38966
|
fixable: false,
|
|
@@ -39112,26 +38971,26 @@ var jsxClasslistStaticKeys = defineCrossRule({
|
|
|
39112
38971
|
forEachClassListPropertyAcross(solids, (solid, p) => {
|
|
39113
38972
|
if (import_typescript128.default.isSpreadAssignment(p)) return;
|
|
39114
38973
|
if (!import_typescript128.default.isPropertyAssignment(p)) {
|
|
39115
|
-
emit(createDiagnostic(solid.file, p, solid.sourceFile, jsxClasslistStaticKeys.id, "nonStaticKey", resolveMessage(
|
|
38974
|
+
emit(createDiagnostic(solid.file, p, solid.sourceFile, jsxClasslistStaticKeys.id, "nonStaticKey", resolveMessage(messages134.nonStaticKey), "error"));
|
|
39116
38975
|
return;
|
|
39117
38976
|
}
|
|
39118
38977
|
if (import_typescript128.default.isComputedPropertyName(p.name)) return;
|
|
39119
38978
|
if (import_typescript128.default.isIdentifier(p.name)) return;
|
|
39120
38979
|
if (import_typescript128.default.isStringLiteral(p.name)) return;
|
|
39121
|
-
emit(createDiagnostic(solid.file, p.name, solid.sourceFile, jsxClasslistStaticKeys.id, "nonStaticKey", resolveMessage(
|
|
38980
|
+
emit(createDiagnostic(solid.file, p.name, solid.sourceFile, jsxClasslistStaticKeys.id, "nonStaticKey", resolveMessage(messages134.nonStaticKey), "error"));
|
|
39122
38981
|
});
|
|
39123
38982
|
}
|
|
39124
38983
|
});
|
|
39125
38984
|
|
|
39126
38985
|
// src/cross-file/rules/jsx-classlist-no-constant-literals.ts
|
|
39127
38986
|
var import_typescript129 = __toESM(require("typescript"), 1);
|
|
39128
|
-
var
|
|
38987
|
+
var messages135 = {
|
|
39129
38988
|
constantEntry: "classList entry `{{name}}: {{value}}` is constant; move it to static class."
|
|
39130
38989
|
};
|
|
39131
38990
|
var jsxClasslistNoConstantLiterals = defineCrossRule({
|
|
39132
38991
|
id: "jsx-classlist-no-constant-literals",
|
|
39133
38992
|
severity: "warn",
|
|
39134
|
-
messages:
|
|
38993
|
+
messages: messages135,
|
|
39135
38994
|
meta: {
|
|
39136
38995
|
description: "Disallow classList entries with constant true/false values.",
|
|
39137
38996
|
fixable: false,
|
|
@@ -39151,7 +39010,7 @@ var jsxClasslistNoConstantLiterals = defineCrossRule({
|
|
|
39151
39010
|
solid.sourceFile,
|
|
39152
39011
|
jsxClasslistNoConstantLiterals.id,
|
|
39153
39012
|
"constantEntry",
|
|
39154
|
-
resolveMessage(
|
|
39013
|
+
resolveMessage(messages135.constantEntry, { name: n, value: val.kind === import_typescript129.default.SyntaxKind.TrueKeyword ? "true" : "false" }),
|
|
39155
39014
|
"warn"
|
|
39156
39015
|
));
|
|
39157
39016
|
});
|
|
@@ -39186,13 +39045,13 @@ function isDefinitelyNonBooleanType(solid, node) {
|
|
|
39186
39045
|
}
|
|
39187
39046
|
|
|
39188
39047
|
// src/cross-file/rules/jsx-classlist-boolean-values.ts
|
|
39189
|
-
var
|
|
39048
|
+
var messages136 = {
|
|
39190
39049
|
nonBooleanValue: "classList value for `{{name}}` must be boolean."
|
|
39191
39050
|
};
|
|
39192
39051
|
var jsxClasslistBooleanValues = defineCrossRule({
|
|
39193
39052
|
id: "jsx-classlist-boolean-values",
|
|
39194
39053
|
severity: "error",
|
|
39195
|
-
messages:
|
|
39054
|
+
messages: messages136,
|
|
39196
39055
|
meta: {
|
|
39197
39056
|
description: "Require classList values to be boolean-like expressions.",
|
|
39198
39057
|
fixable: false,
|
|
@@ -39206,25 +39065,25 @@ var jsxClasslistBooleanValues = defineCrossRule({
|
|
|
39206
39065
|
if (!n) return;
|
|
39207
39066
|
if (isBooleanish(p.initializer)) return;
|
|
39208
39067
|
if (isDefinitelyNonBoolean(p.initializer)) {
|
|
39209
|
-
emit(createDiagnostic(solid.file, p.initializer, solid.sourceFile, jsxClasslistBooleanValues.id, "nonBooleanValue", resolveMessage(
|
|
39068
|
+
emit(createDiagnostic(solid.file, p.initializer, solid.sourceFile, jsxClasslistBooleanValues.id, "nonBooleanValue", resolveMessage(messages136.nonBooleanValue, { name: n }), "error"));
|
|
39210
39069
|
return;
|
|
39211
39070
|
}
|
|
39212
39071
|
if (isBooleanType(solid, p.initializer)) return;
|
|
39213
39072
|
if (!isDefinitelyNonBooleanType(solid, p.initializer)) return;
|
|
39214
|
-
emit(createDiagnostic(solid.file, p.initializer, solid.sourceFile, jsxClasslistBooleanValues.id, "nonBooleanValue", resolveMessage(
|
|
39073
|
+
emit(createDiagnostic(solid.file, p.initializer, solid.sourceFile, jsxClasslistBooleanValues.id, "nonBooleanValue", resolveMessage(messages136.nonBooleanValue, { name: n }), "error"));
|
|
39215
39074
|
});
|
|
39216
39075
|
}
|
|
39217
39076
|
});
|
|
39218
39077
|
|
|
39219
39078
|
// src/cross-file/rules/jsx-classlist-no-accessor-reference.ts
|
|
39220
39079
|
var import_typescript131 = __toESM(require("typescript"), 1);
|
|
39221
|
-
var
|
|
39080
|
+
var messages137 = {
|
|
39222
39081
|
accessorReference: "Signal accessor `{{name}}` must be called in classList value (use {{name}}())."
|
|
39223
39082
|
};
|
|
39224
39083
|
var jsxClasslistNoAccessorReference = defineCrossRule({
|
|
39225
39084
|
id: "jsx-classlist-no-accessor-reference",
|
|
39226
39085
|
severity: "error",
|
|
39227
|
-
messages:
|
|
39086
|
+
messages: messages137,
|
|
39228
39087
|
meta: {
|
|
39229
39088
|
description: "Disallow passing accessor references directly as classList values.",
|
|
39230
39089
|
fixable: false,
|
|
@@ -39256,7 +39115,7 @@ var jsxClasslistNoAccessorReference = defineCrossRule({
|
|
|
39256
39115
|
solid.sourceFile,
|
|
39257
39116
|
jsxClasslistNoAccessorReference.id,
|
|
39258
39117
|
"accessorReference",
|
|
39259
|
-
resolveMessage(
|
|
39118
|
+
resolveMessage(messages137.accessorReference, { name: v.text }),
|
|
39260
39119
|
"error"
|
|
39261
39120
|
));
|
|
39262
39121
|
});
|
|
@@ -39265,13 +39124,13 @@ var jsxClasslistNoAccessorReference = defineCrossRule({
|
|
|
39265
39124
|
|
|
39266
39125
|
// src/cross-file/rules/jsx-style-kebab-case-keys.ts
|
|
39267
39126
|
var import_typescript132 = __toESM(require("typescript"), 1);
|
|
39268
|
-
var
|
|
39127
|
+
var messages138 = {
|
|
39269
39128
|
kebabStyleKey: "Style key `{{name}}` should be `{{kebab}}` in Solid style objects."
|
|
39270
39129
|
};
|
|
39271
39130
|
var jsxStyleKebabCaseKeys = defineCrossRule({
|
|
39272
39131
|
id: "jsx-style-kebab-case-keys",
|
|
39273
39132
|
severity: "error",
|
|
39274
|
-
messages:
|
|
39133
|
+
messages: messages138,
|
|
39275
39134
|
meta: {
|
|
39276
39135
|
description: "Require kebab-case keys in JSX style object literals.",
|
|
39277
39136
|
fixable: false,
|
|
@@ -39292,7 +39151,7 @@ var jsxStyleKebabCaseKeys = defineCrossRule({
|
|
|
39292
39151
|
solid.sourceFile,
|
|
39293
39152
|
jsxStyleKebabCaseKeys.id,
|
|
39294
39153
|
"kebabStyleKey",
|
|
39295
|
-
resolveMessage(
|
|
39154
|
+
resolveMessage(messages138.kebabStyleKey, { name: n, kebab }),
|
|
39296
39155
|
"error"
|
|
39297
39156
|
));
|
|
39298
39157
|
});
|
|
@@ -39301,13 +39160,13 @@ var jsxStyleKebabCaseKeys = defineCrossRule({
|
|
|
39301
39160
|
|
|
39302
39161
|
// src/cross-file/rules/jsx-style-no-function-values.ts
|
|
39303
39162
|
var import_typescript133 = __toESM(require("typescript"), 1);
|
|
39304
|
-
var
|
|
39163
|
+
var messages139 = {
|
|
39305
39164
|
functionStyleValue: "Style value for `{{name}}` is a function; pass computed value instead."
|
|
39306
39165
|
};
|
|
39307
39166
|
var jsxStyleNoFunctionValues = defineCrossRule({
|
|
39308
39167
|
id: "jsx-style-no-function-values",
|
|
39309
39168
|
severity: "error",
|
|
39310
|
-
messages:
|
|
39169
|
+
messages: messages139,
|
|
39311
39170
|
meta: {
|
|
39312
39171
|
description: "Disallow function values in JSX style objects.",
|
|
39313
39172
|
fixable: false,
|
|
@@ -39321,11 +39180,11 @@ var jsxStyleNoFunctionValues = defineCrossRule({
|
|
|
39321
39180
|
if (!n) return;
|
|
39322
39181
|
const v = p.initializer;
|
|
39323
39182
|
if (import_typescript133.default.isArrowFunction(v) || import_typescript133.default.isFunctionExpression(v)) {
|
|
39324
|
-
emit(createDiagnostic(solid.file, v, solid.sourceFile, jsxStyleNoFunctionValues.id, "functionStyleValue", resolveMessage(
|
|
39183
|
+
emit(createDiagnostic(solid.file, v, solid.sourceFile, jsxStyleNoFunctionValues.id, "functionStyleValue", resolveMessage(messages139.functionStyleValue, { name: n }), "error"));
|
|
39325
39184
|
return;
|
|
39326
39185
|
}
|
|
39327
39186
|
if (import_typescript133.default.isIdentifier(v) && solid.typeResolver.isCallableType(v)) {
|
|
39328
|
-
emit(createDiagnostic(solid.file, v, solid.sourceFile, jsxStyleNoFunctionValues.id, "functionStyleValue", resolveMessage(
|
|
39187
|
+
emit(createDiagnostic(solid.file, v, solid.sourceFile, jsxStyleNoFunctionValues.id, "functionStyleValue", resolveMessage(messages139.functionStyleValue, { name: n }), "error"));
|
|
39329
39188
|
}
|
|
39330
39189
|
});
|
|
39331
39190
|
}
|
|
@@ -39333,13 +39192,13 @@ var jsxStyleNoFunctionValues = defineCrossRule({
|
|
|
39333
39192
|
|
|
39334
39193
|
// src/cross-file/rules/jsx-style-no-unused-custom-prop.ts
|
|
39335
39194
|
var import_typescript134 = __toESM(require("typescript"), 1);
|
|
39336
|
-
var
|
|
39195
|
+
var messages140 = {
|
|
39337
39196
|
unusedInlineVar: "Inline custom property `{{name}}` is never read via var({{name}})."
|
|
39338
39197
|
};
|
|
39339
39198
|
var jsxStyleNoUnusedCustomProp = defineCrossRule({
|
|
39340
39199
|
id: "jsx-style-no-unused-custom-prop",
|
|
39341
39200
|
severity: "warn",
|
|
39342
|
-
messages:
|
|
39201
|
+
messages: messages140,
|
|
39343
39202
|
meta: {
|
|
39344
39203
|
description: "Detect inline style custom properties that are never consumed by CSS var() references.",
|
|
39345
39204
|
fixable: false,
|
|
@@ -39380,7 +39239,7 @@ var jsxStyleNoUnusedCustomProp = defineCrossRule({
|
|
|
39380
39239
|
solid.sourceFile,
|
|
39381
39240
|
jsxStyleNoUnusedCustomProp.id,
|
|
39382
39241
|
"unusedInlineVar",
|
|
39383
|
-
resolveMessage(
|
|
39242
|
+
resolveMessage(messages140.unusedInlineVar, { name: n }),
|
|
39384
39243
|
"warn"
|
|
39385
39244
|
));
|
|
39386
39245
|
}
|
|
@@ -39390,7 +39249,7 @@ var jsxStyleNoUnusedCustomProp = defineCrossRule({
|
|
|
39390
39249
|
|
|
39391
39250
|
// src/cross-file/rules/jsx-style-policy.ts
|
|
39392
39251
|
var import_typescript135 = __toESM(require("typescript"), 1);
|
|
39393
|
-
var
|
|
39252
|
+
var messages141 = {
|
|
39394
39253
|
fontTooSmall: "Inline style `{{prop}}: {{value}}` ({{resolved}}px) is below the minimum `{{min}}px` for policy `{{policy}}`.",
|
|
39395
39254
|
lineHeightTooSmall: "Inline style `line-height: {{value}}` is below the minimum `{{min}}` for policy `{{policy}}`.",
|
|
39396
39255
|
heightTooSmall: "Inline style `{{prop}}: {{value}}` ({{resolved}}px) is below the minimum `{{min}}px` for interactive elements in policy `{{policy}}`.",
|
|
@@ -39437,7 +39296,7 @@ function readNodeHostElementRef(layout, solid, element) {
|
|
|
39437
39296
|
var jsxStylePolicy = defineCrossRule({
|
|
39438
39297
|
id: "jsx-style-policy",
|
|
39439
39298
|
severity: "warn",
|
|
39440
|
-
messages:
|
|
39299
|
+
messages: messages141,
|
|
39441
39300
|
meta: {
|
|
39442
39301
|
description: "Enforce accessibility policy thresholds on inline JSX style objects.",
|
|
39443
39302
|
fixable: false,
|
|
@@ -39464,7 +39323,7 @@ var jsxStylePolicy = defineCrossRule({
|
|
|
39464
39323
|
solid.sourceFile,
|
|
39465
39324
|
jsxStylePolicy.id,
|
|
39466
39325
|
"fontTooSmall",
|
|
39467
|
-
resolveMessage(
|
|
39326
|
+
resolveMessage(messages141.fontTooSmall, {
|
|
39468
39327
|
prop: key,
|
|
39469
39328
|
value: strVal,
|
|
39470
39329
|
resolved: formatRounded(px),
|
|
@@ -39486,7 +39345,7 @@ var jsxStylePolicy = defineCrossRule({
|
|
|
39486
39345
|
solid.sourceFile,
|
|
39487
39346
|
jsxStylePolicy.id,
|
|
39488
39347
|
"lineHeightTooSmall",
|
|
39489
|
-
resolveMessage(
|
|
39348
|
+
resolveMessage(messages141.lineHeightTooSmall, {
|
|
39490
39349
|
value: String(lh),
|
|
39491
39350
|
min: String(policy.minLineHeight),
|
|
39492
39351
|
policy: name
|
|
@@ -39510,7 +39369,7 @@ var jsxStylePolicy = defineCrossRule({
|
|
|
39510
39369
|
solid.sourceFile,
|
|
39511
39370
|
jsxStylePolicy.id,
|
|
39512
39371
|
"heightTooSmall",
|
|
39513
|
-
resolveMessage(
|
|
39372
|
+
resolveMessage(messages141.heightTooSmall, {
|
|
39514
39373
|
prop: key,
|
|
39515
39374
|
value: strVal,
|
|
39516
39375
|
resolved: formatRounded(px),
|
|
@@ -39532,7 +39391,7 @@ var jsxStylePolicy = defineCrossRule({
|
|
|
39532
39391
|
solid.sourceFile,
|
|
39533
39392
|
jsxStylePolicy.id,
|
|
39534
39393
|
"letterSpacingTooSmall",
|
|
39535
|
-
resolveMessage(
|
|
39394
|
+
resolveMessage(messages141.letterSpacingTooSmall, {
|
|
39536
39395
|
value: strVal,
|
|
39537
39396
|
resolved: String(em),
|
|
39538
39397
|
min: String(policy.minLetterSpacing),
|
|
@@ -39553,7 +39412,7 @@ var jsxStylePolicy = defineCrossRule({
|
|
|
39553
39412
|
solid.sourceFile,
|
|
39554
39413
|
jsxStylePolicy.id,
|
|
39555
39414
|
"wordSpacingTooSmall",
|
|
39556
|
-
resolveMessage(
|
|
39415
|
+
resolveMessage(messages141.wordSpacingTooSmall, {
|
|
39557
39416
|
value: strVal,
|
|
39558
39417
|
resolved: String(em),
|
|
39559
39418
|
min: String(policy.minWordSpacing),
|
|
@@ -39567,7 +39426,7 @@ var jsxStylePolicy = defineCrossRule({
|
|
|
39567
39426
|
});
|
|
39568
39427
|
|
|
39569
39428
|
// src/cross-file/rules/css-layout-sibling-alignment-outlier.ts
|
|
39570
|
-
var
|
|
39429
|
+
var messages142 = {
|
|
39571
39430
|
misalignedSibling: "Vertically misaligned '{{subject}}' in '{{parent}}'.{{fix}}{{offsetClause}}"
|
|
39572
39431
|
};
|
|
39573
39432
|
var MIN_CONFIDENCE_THRESHOLD = 0.48;
|
|
@@ -39615,7 +39474,7 @@ var siblingAlignmentDetector = {
|
|
|
39615
39474
|
var cssLayoutSiblingAlignmentOutlier = defineCrossRule({
|
|
39616
39475
|
id: "css-layout-sibling-alignment-outlier",
|
|
39617
39476
|
severity: "warn",
|
|
39618
|
-
messages:
|
|
39477
|
+
messages: messages142,
|
|
39619
39478
|
meta: {
|
|
39620
39479
|
description: "Detect vertical alignment outliers between sibling elements in shared layout containers.",
|
|
39621
39480
|
fixable: false,
|
|
@@ -39699,7 +39558,7 @@ var cssLayoutSiblingAlignmentOutlier = defineCrossRule({
|
|
|
39699
39558
|
subjectRef.solid.sourceFile,
|
|
39700
39559
|
cssLayoutSiblingAlignmentOutlier.id,
|
|
39701
39560
|
"misalignedSibling",
|
|
39702
|
-
resolveMessage(
|
|
39561
|
+
resolveMessage(messages142.misalignedSibling, {
|
|
39703
39562
|
subject,
|
|
39704
39563
|
parent,
|
|
39705
39564
|
fix,
|
|
@@ -39783,13 +39642,13 @@ function hasNonOffsetPrimaryEvidence(topFactors) {
|
|
|
39783
39642
|
}
|
|
39784
39643
|
|
|
39785
39644
|
// src/cross-file/rules/css-layout-transition-layout-property.ts
|
|
39786
|
-
var
|
|
39645
|
+
var messages143 = {
|
|
39787
39646
|
transitionLayoutProperty: "Transition '{{property}}' in '{{declaration}}' animates layout-affecting geometry. Prefer transform/opacity to avoid CLS."
|
|
39788
39647
|
};
|
|
39789
39648
|
var cssLayoutTransitionLayoutProperty = defineCrossRule({
|
|
39790
39649
|
id: "css-layout-transition-layout-property",
|
|
39791
39650
|
severity: "warn",
|
|
39792
|
-
messages:
|
|
39651
|
+
messages: messages143,
|
|
39793
39652
|
meta: {
|
|
39794
39653
|
description: "Disallow transitions that animate layout-affecting geometry properties.",
|
|
39795
39654
|
fixable: false,
|
|
@@ -39813,7 +39672,7 @@ var cssLayoutTransitionLayoutProperty = defineCrossRule({
|
|
|
39813
39672
|
},
|
|
39814
39673
|
cssLayoutTransitionLayoutProperty.id,
|
|
39815
39674
|
"transitionLayoutProperty",
|
|
39816
|
-
resolveMessage(
|
|
39675
|
+
resolveMessage(messages143.transitionLayoutProperty, {
|
|
39817
39676
|
property: target,
|
|
39818
39677
|
declaration: declaration.property
|
|
39819
39678
|
}),
|
|
@@ -39828,13 +39687,13 @@ function findLayoutTransitionTarget(raw) {
|
|
|
39828
39687
|
}
|
|
39829
39688
|
|
|
39830
39689
|
// src/cross-file/rules/css-layout-animation-layout-property.ts
|
|
39831
|
-
var
|
|
39690
|
+
var messages144 = {
|
|
39832
39691
|
animationLayoutProperty: "Animation '{{animation}}' mutates layout-affecting '{{property}}', which can trigger CLS. Prefer transform/opacity or reserve geometry."
|
|
39833
39692
|
};
|
|
39834
39693
|
var cssLayoutAnimationLayoutProperty = defineCrossRule({
|
|
39835
39694
|
id: "css-layout-animation-layout-property",
|
|
39836
39695
|
severity: "warn",
|
|
39837
|
-
messages:
|
|
39696
|
+
messages: messages144,
|
|
39838
39697
|
meta: {
|
|
39839
39698
|
description: "Disallow keyframe animations that mutate layout-affecting properties and can trigger CLS.",
|
|
39840
39699
|
fixable: false,
|
|
@@ -39862,7 +39721,7 @@ var cssLayoutAnimationLayoutProperty = defineCrossRule({
|
|
|
39862
39721
|
},
|
|
39863
39722
|
cssLayoutAnimationLayoutProperty.id,
|
|
39864
39723
|
"animationLayoutProperty",
|
|
39865
|
-
resolveMessage(
|
|
39724
|
+
resolveMessage(messages144.animationLayoutProperty, {
|
|
39866
39725
|
animation: match.name,
|
|
39867
39726
|
property: match.property
|
|
39868
39727
|
}),
|
|
@@ -39932,13 +39791,13 @@ function firstRiskyAnimationName(names, riskyKeyframes) {
|
|
|
39932
39791
|
}
|
|
39933
39792
|
|
|
39934
39793
|
// src/cross-file/rules/css-layout-stateful-box-model-shift.ts
|
|
39935
|
-
var
|
|
39794
|
+
var messages145 = {
|
|
39936
39795
|
statefulBoxModelShift: "State selector '{{selector}}' changes layout-affecting '{{property}}'. Keep geometry stable across states to avoid CLS."
|
|
39937
39796
|
};
|
|
39938
39797
|
var cssLayoutStatefulBoxModelShift = defineCrossRule({
|
|
39939
39798
|
id: "css-layout-stateful-box-model-shift",
|
|
39940
39799
|
severity: "warn",
|
|
39941
|
-
messages:
|
|
39800
|
+
messages: messages145,
|
|
39942
39801
|
meta: {
|
|
39943
39802
|
description: "Disallow stateful selector changes that alter element geometry and trigger layout shifts.",
|
|
39944
39803
|
fixable: false,
|
|
@@ -39979,7 +39838,7 @@ var cssLayoutStatefulBoxModelShift = defineCrossRule({
|
|
|
39979
39838
|
},
|
|
39980
39839
|
cssLayoutStatefulBoxModelShift.id,
|
|
39981
39840
|
"statefulBoxModelShift",
|
|
39982
|
-
resolveMessage(
|
|
39841
|
+
resolveMessage(messages145.statefulBoxModelShift, {
|
|
39983
39842
|
selector: match.raw,
|
|
39984
39843
|
property: declaration.property
|
|
39985
39844
|
}),
|
|
@@ -40073,14 +39932,14 @@ function lookupBaseByProperty(baseValueIndex, selectorKeys) {
|
|
|
40073
39932
|
|
|
40074
39933
|
// src/cross-file/rules/css-layout-unsized-replaced-element.ts
|
|
40075
39934
|
var import_typescript136 = __toESM(require("typescript"), 1);
|
|
40076
|
-
var
|
|
39935
|
+
var messages146 = {
|
|
40077
39936
|
unsizedReplacedElement: "Replaced element '{{tag}}' has no stable reserved size (width/height or aspect-ratio with a dimension), which can cause CLS."
|
|
40078
39937
|
};
|
|
40079
39938
|
var REPLACED_MEDIA_TAGS = /* @__PURE__ */ new Set(["img", "video", "iframe", "canvas", "svg"]);
|
|
40080
39939
|
var cssLayoutUnsizedReplacedElement = defineCrossRule({
|
|
40081
39940
|
id: "css-layout-unsized-replaced-element",
|
|
40082
39941
|
severity: "warn",
|
|
40083
|
-
messages:
|
|
39942
|
+
messages: messages146,
|
|
40084
39943
|
meta: {
|
|
40085
39944
|
description: "Require stable reserved geometry for replaced media elements to prevent layout shifts.",
|
|
40086
39945
|
fixable: false,
|
|
@@ -40105,7 +39964,7 @@ var cssLayoutUnsizedReplacedElement = defineCrossRule({
|
|
|
40105
39964
|
ref.solid.sourceFile,
|
|
40106
39965
|
cssLayoutUnsizedReplacedElement.id,
|
|
40107
39966
|
"unsizedReplacedElement",
|
|
40108
|
-
resolveMessage(
|
|
39967
|
+
resolveMessage(messages146.unsizedReplacedElement, { tag }),
|
|
40109
39968
|
"warn"
|
|
40110
39969
|
)
|
|
40111
39970
|
);
|
|
@@ -40158,7 +40017,7 @@ function readPositiveJsxAttribute(solid, element, name) {
|
|
|
40158
40017
|
}
|
|
40159
40018
|
|
|
40160
40019
|
// src/cross-file/rules/css-layout-dynamic-slot-no-reserved-space.ts
|
|
40161
|
-
var
|
|
40020
|
+
var messages147 = {
|
|
40162
40021
|
dynamicSlotNoReservedSpace: "Dynamic content container '{{tag}}' does not reserve block space (min-height/height/aspect-ratio/contain-intrinsic-size), which can cause CLS."
|
|
40163
40022
|
};
|
|
40164
40023
|
var INLINE_DISPLAYS = /* @__PURE__ */ new Set(["inline", "contents"]);
|
|
@@ -40180,7 +40039,7 @@ function hasOutOfFlowAncestor(layout, node) {
|
|
|
40180
40039
|
var cssLayoutDynamicSlotNoReservedSpace = defineCrossRule({
|
|
40181
40040
|
id: "css-layout-dynamic-slot-no-reserved-space",
|
|
40182
40041
|
severity: "warn",
|
|
40183
|
-
messages:
|
|
40042
|
+
messages: messages147,
|
|
40184
40043
|
meta: {
|
|
40185
40044
|
description: "Require reserved block space for dynamic content containers to avoid layout shifts.",
|
|
40186
40045
|
fixable: false,
|
|
@@ -40203,19 +40062,19 @@ var cssLayoutDynamicSlotNoReservedSpace = defineCrossRule({
|
|
|
40203
40062
|
const reservedSpace = readReservedSpaceFact(context.layout, node);
|
|
40204
40063
|
if (reservedSpace.hasReservedSpace) continue;
|
|
40205
40064
|
if (hasBlockAxisPadding(snapshot)) continue;
|
|
40206
|
-
if (!emitLayoutDiagnostic(context.layout, node, emit, cssLayoutDynamicSlotNoReservedSpace.id, "dynamicSlotNoReservedSpace",
|
|
40065
|
+
if (!emitLayoutDiagnostic(context.layout, node, emit, cssLayoutDynamicSlotNoReservedSpace.id, "dynamicSlotNoReservedSpace", messages147.dynamicSlotNoReservedSpace, cssLayoutDynamicSlotNoReservedSpace.severity)) continue;
|
|
40207
40066
|
}
|
|
40208
40067
|
}
|
|
40209
40068
|
});
|
|
40210
40069
|
|
|
40211
40070
|
// src/cross-file/rules/css-layout-scrollbar-gutter-instability.ts
|
|
40212
|
-
var
|
|
40071
|
+
var messages148 = {
|
|
40213
40072
|
missingScrollbarGutter: "Scrollable container '{{tag}}' uses overflow auto/scroll without `scrollbar-gutter: stable`, which can trigger CLS when scrollbars appear."
|
|
40214
40073
|
};
|
|
40215
40074
|
var cssLayoutScrollbarGutterInstability = defineCrossRule({
|
|
40216
40075
|
id: "css-layout-scrollbar-gutter-instability",
|
|
40217
40076
|
severity: "warn",
|
|
40218
|
-
messages:
|
|
40077
|
+
messages: messages148,
|
|
40219
40078
|
meta: {
|
|
40220
40079
|
description: "Require stable scrollbar gutters for scrollable containers to reduce layout shifts.",
|
|
40221
40080
|
fixable: false,
|
|
@@ -40234,19 +40093,19 @@ var cssLayoutScrollbarGutterInstability = defineCrossRule({
|
|
|
40234
40093
|
if (scrollbarWidth === "none") continue;
|
|
40235
40094
|
const gutter = readKnownNormalized(snapshot, "scrollbar-gutter");
|
|
40236
40095
|
if (gutter !== null && gutter.startsWith("stable")) continue;
|
|
40237
|
-
if (!emitLayoutDiagnostic(context.layout, node, emit, cssLayoutScrollbarGutterInstability.id, "missingScrollbarGutter",
|
|
40096
|
+
if (!emitLayoutDiagnostic(context.layout, node, emit, cssLayoutScrollbarGutterInstability.id, "missingScrollbarGutter", messages148.missingScrollbarGutter, cssLayoutScrollbarGutterInstability.severity)) continue;
|
|
40238
40097
|
}
|
|
40239
40098
|
}
|
|
40240
40099
|
});
|
|
40241
40100
|
|
|
40242
40101
|
// src/cross-file/rules/css-layout-overflow-anchor-instability.ts
|
|
40243
|
-
var
|
|
40102
|
+
var messages149 = {
|
|
40244
40103
|
unstableOverflowAnchor: "Element '{{tag}}' sets `overflow-anchor: none` on a {{context}} container; disabling scroll anchoring can amplify visible layout shifts."
|
|
40245
40104
|
};
|
|
40246
40105
|
var cssLayoutOverflowAnchorInstability = defineCrossRule({
|
|
40247
40106
|
id: "css-layout-overflow-anchor-instability",
|
|
40248
40107
|
severity: "warn",
|
|
40249
|
-
messages:
|
|
40108
|
+
messages: messages149,
|
|
40250
40109
|
meta: {
|
|
40251
40110
|
description: "Disallow overflow-anchor none on dynamic or scrollable containers prone to visible layout shifts.",
|
|
40252
40111
|
fixable: false,
|
|
@@ -40264,20 +40123,20 @@ var cssLayoutOverflowAnchorInstability = defineCrossRule({
|
|
|
40264
40123
|
const isDynamicContainer = isDynamicContainerLike(node);
|
|
40265
40124
|
if (!isScrollable && !isDynamicContainer) continue;
|
|
40266
40125
|
const containerContext = isScrollable ? "scrollable" : "dynamic";
|
|
40267
|
-
if (!emitLayoutDiagnostic(context.layout, node, emit, cssLayoutOverflowAnchorInstability.id, "unstableOverflowAnchor",
|
|
40126
|
+
if (!emitLayoutDiagnostic(context.layout, node, emit, cssLayoutOverflowAnchorInstability.id, "unstableOverflowAnchor", messages149.unstableOverflowAnchor, cssLayoutOverflowAnchorInstability.severity, { context: containerContext })) continue;
|
|
40268
40127
|
}
|
|
40269
40128
|
}
|
|
40270
40129
|
});
|
|
40271
40130
|
|
|
40272
40131
|
// src/cross-file/rules/css-layout-font-swap-instability.ts
|
|
40273
|
-
var
|
|
40132
|
+
var messages150 = {
|
|
40274
40133
|
unstableFontSwap: "`@font-face` for '{{family}}' uses `font-display: {{display}}` without metric overrides (for example `size-adjust`), which can cause CLS when the webfont swaps in."
|
|
40275
40134
|
};
|
|
40276
40135
|
var SWAP_DISPLAYS = /* @__PURE__ */ new Set(["swap", "fallback"]);
|
|
40277
40136
|
var cssLayoutFontSwapInstability = defineCrossRule({
|
|
40278
40137
|
id: "css-layout-font-swap-instability",
|
|
40279
40138
|
severity: "warn",
|
|
40280
|
-
messages:
|
|
40139
|
+
messages: messages150,
|
|
40281
40140
|
meta: {
|
|
40282
40141
|
description: "Require metric overrides for swapping webfonts to reduce layout shifts during font load.",
|
|
40283
40142
|
fixable: false,
|
|
@@ -40324,7 +40183,7 @@ var cssLayoutFontSwapInstability = defineCrossRule({
|
|
|
40324
40183
|
},
|
|
40325
40184
|
cssLayoutFontSwapInstability.id,
|
|
40326
40185
|
"unstableFontSwap",
|
|
40327
|
-
resolveMessage(
|
|
40186
|
+
resolveMessage(messages150.unstableFontSwap, {
|
|
40328
40187
|
family,
|
|
40329
40188
|
display: report.display
|
|
40330
40189
|
}),
|
|
@@ -40337,14 +40196,14 @@ var cssLayoutFontSwapInstability = defineCrossRule({
|
|
|
40337
40196
|
});
|
|
40338
40197
|
|
|
40339
40198
|
// src/cross-file/rules/css-layout-conditional-display-collapse.ts
|
|
40340
|
-
var
|
|
40199
|
+
var messages151 = {
|
|
40341
40200
|
conditionalDisplayCollapse: "Conditional display sets '{{display}}' on '{{tag}}' without stable reserved space, which can collapse/expand layout and cause CLS."
|
|
40342
40201
|
};
|
|
40343
40202
|
var COLLAPSING_DISPLAYS = /* @__PURE__ */ new Set(["none", "contents"]);
|
|
40344
40203
|
var cssLayoutConditionalDisplayCollapse = defineCrossRule({
|
|
40345
40204
|
id: "css-layout-conditional-display-collapse",
|
|
40346
40205
|
severity: "warn",
|
|
40347
|
-
messages:
|
|
40206
|
+
messages: messages151,
|
|
40348
40207
|
meta: {
|
|
40349
40208
|
description: "Disallow conditional display collapse in flow without reserved geometry.",
|
|
40350
40209
|
fixable: false,
|
|
@@ -40365,13 +40224,13 @@ var cssLayoutConditionalDisplayCollapse = defineCrossRule({
|
|
|
40365
40224
|
if (!isFlowRelevantBySiblingsOrText(node, snapshot.node.textualContent)) continue;
|
|
40366
40225
|
const reservedSpace = readReservedSpaceFact(context.layout, node);
|
|
40367
40226
|
if (reservedSpace.hasReservedSpace) continue;
|
|
40368
|
-
if (!emitLayoutDiagnostic(context.layout, node, emit, cssLayoutConditionalDisplayCollapse.id, "conditionalDisplayCollapse",
|
|
40227
|
+
if (!emitLayoutDiagnostic(context.layout, node, emit, cssLayoutConditionalDisplayCollapse.id, "conditionalDisplayCollapse", messages151.conditionalDisplayCollapse, cssLayoutConditionalDisplayCollapse.severity, { display })) continue;
|
|
40369
40228
|
}
|
|
40370
40229
|
}
|
|
40371
40230
|
});
|
|
40372
40231
|
|
|
40373
40232
|
// src/cross-file/rules/css-layout-conditional-white-space-wrap-shift.ts
|
|
40374
|
-
var
|
|
40233
|
+
var messages152 = {
|
|
40375
40234
|
conditionalWhiteSpaceShift: "Conditional white-space '{{whiteSpace}}' on '{{tag}}' can reflow text and shift siblings; keep wrapping behavior stable or reserve geometry."
|
|
40376
40235
|
};
|
|
40377
40236
|
var WRAP_SHIFT_VALUES = /* @__PURE__ */ new Set(["nowrap", "pre"]);
|
|
@@ -40380,7 +40239,7 @@ var BLOCK_SIZE_PROPERTIES = ["height", "min-height"];
|
|
|
40380
40239
|
var cssLayoutConditionalWhiteSpaceWrapShift = defineCrossRule({
|
|
40381
40240
|
id: "css-layout-conditional-white-space-wrap-shift",
|
|
40382
40241
|
severity: "warn",
|
|
40383
|
-
messages:
|
|
40242
|
+
messages: messages152,
|
|
40384
40243
|
meta: {
|
|
40385
40244
|
description: "Disallow conditional white-space wrapping mode toggles that can trigger CLS.",
|
|
40386
40245
|
fixable: false,
|
|
@@ -40403,7 +40262,7 @@ var cssLayoutConditionalWhiteSpaceWrapShift = defineCrossRule({
|
|
|
40403
40262
|
if (!flow.inFlow) continue;
|
|
40404
40263
|
if (!isFlowRelevantBySiblingsOrText(node, snapshot.node.textualContent)) continue;
|
|
40405
40264
|
if (hasStableTextShell(snapshot)) continue;
|
|
40406
|
-
if (!emitLayoutDiagnostic(context.layout, node, emit, cssLayoutConditionalWhiteSpaceWrapShift.id, "conditionalWhiteSpaceShift",
|
|
40265
|
+
if (!emitLayoutDiagnostic(context.layout, node, emit, cssLayoutConditionalWhiteSpaceWrapShift.id, "conditionalWhiteSpaceShift", messages152.conditionalWhiteSpaceShift, cssLayoutConditionalWhiteSpaceWrapShift.severity, { whiteSpace })) continue;
|
|
40407
40266
|
}
|
|
40408
40267
|
}
|
|
40409
40268
|
});
|
|
@@ -40425,13 +40284,13 @@ function hasWrapShiftDelta(delta) {
|
|
|
40425
40284
|
}
|
|
40426
40285
|
|
|
40427
40286
|
// src/cross-file/rules/css-layout-overflow-mode-toggle-instability.ts
|
|
40428
|
-
var
|
|
40287
|
+
var messages153 = {
|
|
40429
40288
|
overflowModeToggle: "Conditional overflow mode changes scrolling ('{{overflow}}') on '{{tag}}' without `scrollbar-gutter: stable`, which can trigger CLS."
|
|
40430
40289
|
};
|
|
40431
40290
|
var cssLayoutOverflowModeToggleInstability = defineCrossRule({
|
|
40432
40291
|
id: "css-layout-overflow-mode-toggle-instability",
|
|
40433
40292
|
severity: "warn",
|
|
40434
|
-
messages:
|
|
40293
|
+
messages: messages153,
|
|
40435
40294
|
meta: {
|
|
40436
40295
|
description: "Disallow conditional overflow mode switches that can introduce scrollbar-induced layout shifts.",
|
|
40437
40296
|
fixable: false,
|
|
@@ -40456,7 +40315,7 @@ var cssLayoutOverflowModeToggleInstability = defineCrossRule({
|
|
|
40456
40315
|
const gutter = readKnownNormalizedWithGuard(snapshot, "scrollbar-gutter");
|
|
40457
40316
|
if (gutter !== null && gutter.startsWith("stable")) continue;
|
|
40458
40317
|
const overflowValue = scrollFact.overflowY ?? scrollFact.overflow ?? "auto";
|
|
40459
|
-
if (!emitLayoutDiagnostic(context.layout, node, emit, cssLayoutOverflowModeToggleInstability.id, "overflowModeToggle",
|
|
40318
|
+
if (!emitLayoutDiagnostic(context.layout, node, emit, cssLayoutOverflowModeToggleInstability.id, "overflowModeToggle", messages153.overflowModeToggle, cssLayoutOverflowModeToggleInstability.severity, { overflow: overflowValue })) continue;
|
|
40460
40319
|
}
|
|
40461
40320
|
}
|
|
40462
40321
|
});
|
|
@@ -40476,7 +40335,7 @@ function hasAnyScrollValue(delta) {
|
|
|
40476
40335
|
}
|
|
40477
40336
|
|
|
40478
40337
|
// src/cross-file/rules/css-layout-box-sizing-toggle-with-chrome.ts
|
|
40479
|
-
var
|
|
40338
|
+
var messages154 = {
|
|
40480
40339
|
boxSizingToggleWithChrome: "Conditional `box-sizing` toggle on '{{tag}}' combines with non-zero padding/border, which can shift layout and trigger CLS."
|
|
40481
40340
|
};
|
|
40482
40341
|
var BOX_SIZING_VALUES = /* @__PURE__ */ new Set(["content-box", "border-box"]);
|
|
@@ -40493,7 +40352,7 @@ var CHROME_PROPERTIES = [
|
|
|
40493
40352
|
var cssLayoutBoxSizingToggleWithChrome = defineCrossRule({
|
|
40494
40353
|
id: "css-layout-box-sizing-toggle-with-chrome",
|
|
40495
40354
|
severity: "warn",
|
|
40496
|
-
messages:
|
|
40355
|
+
messages: messages154,
|
|
40497
40356
|
meta: {
|
|
40498
40357
|
description: "Disallow conditional box-sizing mode toggles when box chrome contributes to geometry shifts.",
|
|
40499
40358
|
fixable: false,
|
|
@@ -40511,7 +40370,7 @@ var cssLayoutBoxSizingToggleWithChrome = defineCrossRule({
|
|
|
40511
40370
|
if (!boxSizingDelta.hasConditional) continue;
|
|
40512
40371
|
if (!boxSizingDelta.hasDelta) continue;
|
|
40513
40372
|
if (!hasNonZeroChrome(snapshot)) continue;
|
|
40514
|
-
if (!emitLayoutDiagnostic(context.layout, node, emit, cssLayoutBoxSizingToggleWithChrome.id, "boxSizingToggleWithChrome",
|
|
40373
|
+
if (!emitLayoutDiagnostic(context.layout, node, emit, cssLayoutBoxSizingToggleWithChrome.id, "boxSizingToggleWithChrome", messages154.boxSizingToggleWithChrome, cssLayoutBoxSizingToggleWithChrome.severity)) continue;
|
|
40515
40374
|
}
|
|
40516
40375
|
}
|
|
40517
40376
|
});
|
|
@@ -40520,13 +40379,13 @@ function hasNonZeroChrome(snapshot) {
|
|
|
40520
40379
|
}
|
|
40521
40380
|
|
|
40522
40381
|
// src/cross-file/rules/css-layout-content-visibility-no-intrinsic-size.ts
|
|
40523
|
-
var
|
|
40382
|
+
var messages155 = {
|
|
40524
40383
|
missingIntrinsicSize: "`content-visibility: auto` on '{{tag}}' lacks intrinsic size reservation (`contain-intrinsic-size`/min-height/height/aspect-ratio), which can cause CLS."
|
|
40525
40384
|
};
|
|
40526
40385
|
var cssLayoutContentVisibilityNoIntrinsicSize = defineCrossRule({
|
|
40527
40386
|
id: "css-layout-content-visibility-no-intrinsic-size",
|
|
40528
40387
|
severity: "warn",
|
|
40529
|
-
messages:
|
|
40388
|
+
messages: messages155,
|
|
40530
40389
|
meta: {
|
|
40531
40390
|
description: "Require intrinsic size reservation when using content-visibility auto to avoid late layout shifts.",
|
|
40532
40391
|
fixable: false,
|
|
@@ -40541,19 +40400,19 @@ var cssLayoutContentVisibilityNoIntrinsicSize = defineCrossRule({
|
|
|
40541
40400
|
if (!isDeferredContainerLike(node, snapshot.node.textualContent)) continue;
|
|
40542
40401
|
const reservedSpace = readReservedSpaceFact(context.layout, node);
|
|
40543
40402
|
if (reservedSpace.hasReservedSpace) continue;
|
|
40544
|
-
if (!emitLayoutDiagnostic(context.layout, node, emit, cssLayoutContentVisibilityNoIntrinsicSize.id, "missingIntrinsicSize",
|
|
40403
|
+
if (!emitLayoutDiagnostic(context.layout, node, emit, cssLayoutContentVisibilityNoIntrinsicSize.id, "missingIntrinsicSize", messages155.missingIntrinsicSize, cssLayoutContentVisibilityNoIntrinsicSize.severity)) continue;
|
|
40545
40404
|
}
|
|
40546
40405
|
}
|
|
40547
40406
|
});
|
|
40548
40407
|
|
|
40549
40408
|
// src/cross-file/rules/css-layout-conditional-offset-shift.ts
|
|
40550
|
-
var
|
|
40409
|
+
var messages156 = {
|
|
40551
40410
|
conditionalOffsetShift: "Conditional style applies non-zero '{{property}}' offset ({{value}}), which can cause layout shifts when conditions toggle."
|
|
40552
40411
|
};
|
|
40553
40412
|
var cssLayoutConditionalOffsetShift = defineCrossRule({
|
|
40554
40413
|
id: "css-layout-conditional-offset-shift",
|
|
40555
40414
|
severity: "warn",
|
|
40556
|
-
messages:
|
|
40415
|
+
messages: messages156,
|
|
40557
40416
|
meta: {
|
|
40558
40417
|
description: "Disallow conditional non-zero block-axis offsets that can trigger layout shifts.",
|
|
40559
40418
|
fixable: false,
|
|
@@ -40579,7 +40438,7 @@ var cssLayoutConditionalOffsetShift = defineCrossRule({
|
|
|
40579
40438
|
ref.solid.sourceFile,
|
|
40580
40439
|
cssLayoutConditionalOffsetShift.id,
|
|
40581
40440
|
"conditionalOffsetShift",
|
|
40582
|
-
resolveMessage(
|
|
40441
|
+
resolveMessage(messages156.conditionalOffsetShift, {
|
|
40583
40442
|
property: match.property,
|
|
40584
40443
|
value: `${formatFixed(match.value)}px`
|
|
40585
40444
|
}),
|
|
@@ -40640,7 +40499,7 @@ function hasStableBaseline(baselineBySignal, property, expectedPx) {
|
|
|
40640
40499
|
|
|
40641
40500
|
// src/cross-file/rules/jsx-layout-unstable-style-toggle.ts
|
|
40642
40501
|
var import_typescript137 = __toESM(require("typescript"), 1);
|
|
40643
|
-
var
|
|
40502
|
+
var messages157 = {
|
|
40644
40503
|
unstableLayoutStyleToggle: "Dynamic style value for '{{property}}' can toggle layout geometry at runtime and cause CLS."
|
|
40645
40504
|
};
|
|
40646
40505
|
var PX_NUMBER_PROPERTIES = /* @__PURE__ */ new Set([
|
|
@@ -40663,7 +40522,7 @@ var POSITIONED_OFFSET_PROPERTIES = /* @__PURE__ */ new Set([
|
|
|
40663
40522
|
var jsxLayoutUnstableStyleToggle = defineCrossRule({
|
|
40664
40523
|
id: "jsx-layout-unstable-style-toggle",
|
|
40665
40524
|
severity: "warn",
|
|
40666
|
-
messages:
|
|
40525
|
+
messages: messages157,
|
|
40667
40526
|
meta: {
|
|
40668
40527
|
description: "Flag dynamic inline style values on layout-sensitive properties that can trigger CLS.",
|
|
40669
40528
|
fixable: false,
|
|
@@ -40685,7 +40544,7 @@ var jsxLayoutUnstableStyleToggle = defineCrossRule({
|
|
|
40685
40544
|
solid.sourceFile,
|
|
40686
40545
|
jsxLayoutUnstableStyleToggle.id,
|
|
40687
40546
|
"unstableLayoutStyleToggle",
|
|
40688
|
-
resolveMessage(
|
|
40547
|
+
resolveMessage(messages157.unstableLayoutStyleToggle, { property: normalized }),
|
|
40689
40548
|
"warn"
|
|
40690
40549
|
)
|
|
40691
40550
|
);
|
|
@@ -40802,14 +40661,14 @@ function unwrapTypeWrapper(node) {
|
|
|
40802
40661
|
|
|
40803
40662
|
// src/cross-file/rules/jsx-layout-classlist-geometry-toggle.ts
|
|
40804
40663
|
var import_typescript138 = __toESM(require("typescript"), 1);
|
|
40805
|
-
var
|
|
40664
|
+
var messages158 = {
|
|
40806
40665
|
classListGeometryToggle: "classList toggles '{{className}}', and matching CSS changes layout-affecting '{{property}}', which can cause CLS."
|
|
40807
40666
|
};
|
|
40808
40667
|
var OUT_OF_FLOW_POSITIONS2 = /* @__PURE__ */ new Set(["fixed", "absolute"]);
|
|
40809
40668
|
var jsxLayoutClasslistGeometryToggle = defineCrossRule({
|
|
40810
40669
|
id: "jsx-layout-classlist-geometry-toggle",
|
|
40811
40670
|
severity: "warn",
|
|
40812
|
-
messages:
|
|
40671
|
+
messages: messages158,
|
|
40813
40672
|
meta: {
|
|
40814
40673
|
description: "Flag classList-driven class toggles that map to layout-affecting CSS geometry changes.",
|
|
40815
40674
|
fixable: false,
|
|
@@ -40835,7 +40694,7 @@ var jsxLayoutClasslistGeometryToggle = defineCrossRule({
|
|
|
40835
40694
|
solid.sourceFile,
|
|
40836
40695
|
jsxLayoutClasslistGeometryToggle.id,
|
|
40837
40696
|
"classListGeometryToggle",
|
|
40838
|
-
resolveMessage(
|
|
40697
|
+
resolveMessage(messages158.classListGeometryToggle, {
|
|
40839
40698
|
className,
|
|
40840
40699
|
property
|
|
40841
40700
|
}),
|
|
@@ -40884,14 +40743,14 @@ function isDynamicallyToggleable(node) {
|
|
|
40884
40743
|
}
|
|
40885
40744
|
|
|
40886
40745
|
// src/cross-file/rules/jsx-layout-picture-source-ratio-consistency.ts
|
|
40887
|
-
var
|
|
40746
|
+
var messages159 = {
|
|
40888
40747
|
inconsistentPictureRatio: "`<picture>` source ratio {{sourceRatio}} differs from fallback img ratio {{imgRatio}}, which can cause reserved-space mismatch and CLS."
|
|
40889
40748
|
};
|
|
40890
40749
|
var RATIO_DELTA_THRESHOLD = 0.02;
|
|
40891
40750
|
var jsxLayoutPictureSourceRatioConsistency = defineCrossRule({
|
|
40892
40751
|
id: "jsx-layout-picture-source-ratio-consistency",
|
|
40893
40752
|
severity: "warn",
|
|
40894
|
-
messages:
|
|
40753
|
+
messages: messages159,
|
|
40895
40754
|
meta: {
|
|
40896
40755
|
description: "Require consistent intrinsic aspect ratios across <picture> sources and fallback image.",
|
|
40897
40756
|
fixable: false,
|
|
@@ -40914,7 +40773,7 @@ var jsxLayoutPictureSourceRatioConsistency = defineCrossRule({
|
|
|
40914
40773
|
solid.sourceFile,
|
|
40915
40774
|
jsxLayoutPictureSourceRatioConsistency.id,
|
|
40916
40775
|
"inconsistentPictureRatio",
|
|
40917
|
-
resolveMessage(
|
|
40776
|
+
resolveMessage(messages159.inconsistentPictureRatio, {
|
|
40918
40777
|
sourceRatio: mismatch.sourceRatio,
|
|
40919
40778
|
imgRatio: mismatch.imgRatio
|
|
40920
40779
|
}),
|
|
@@ -40984,13 +40843,13 @@ function formatRatio(value2) {
|
|
|
40984
40843
|
}
|
|
40985
40844
|
|
|
40986
40845
|
// src/cross-file/rules/jsx-layout-fill-image-parent-must-be-sized.ts
|
|
40987
|
-
var
|
|
40846
|
+
var messages160 = {
|
|
40988
40847
|
unsizedFillParent: "Fill-image component '{{component}}' is inside a parent without stable size/position; add parent sizing (height/min-height/aspect-ratio) and non-static position to avoid CLS."
|
|
40989
40848
|
};
|
|
40990
40849
|
var jsxLayoutFillImageParentMustBeSized = defineCrossRule({
|
|
40991
40850
|
id: "jsx-layout-fill-image-parent-must-be-sized",
|
|
40992
40851
|
severity: "warn",
|
|
40993
|
-
messages:
|
|
40852
|
+
messages: messages160,
|
|
40994
40853
|
meta: {
|
|
40995
40854
|
description: "Require stable parent size and positioning for fill-image component usage.",
|
|
40996
40855
|
fixable: false,
|
|
@@ -41020,7 +40879,7 @@ var jsxLayoutFillImageParentMustBeSized = defineCrossRule({
|
|
|
41020
40879
|
solid.sourceFile,
|
|
41021
40880
|
jsxLayoutFillImageParentMustBeSized.id,
|
|
41022
40881
|
"unsizedFillParent",
|
|
41023
|
-
resolveMessage(
|
|
40882
|
+
resolveMessage(messages160.unsizedFillParent, {
|
|
41024
40883
|
component: element.tag ?? "Image"
|
|
41025
40884
|
}),
|
|
41026
40885
|
"warn"
|
|
@@ -41031,6 +40890,210 @@ var jsxLayoutFillImageParentMustBeSized = defineCrossRule({
|
|
|
41031
40890
|
}
|
|
41032
40891
|
});
|
|
41033
40892
|
|
|
40893
|
+
// src/cross-file/rules/jsx-layout-policy-touch-target.ts
|
|
40894
|
+
var messages161 = {
|
|
40895
|
+
heightTooSmall: "`{{signal}}` of `{{value}}px` is below the minimum `{{min}}px` for interactive element `<{{tag}}>` in policy `{{policy}}`.",
|
|
40896
|
+
widthTooSmall: "`{{signal}}` of `{{value}}px` is below the minimum `{{min}}px` for interactive element `<{{tag}}>` in policy `{{policy}}`.",
|
|
40897
|
+
paddingTooSmall: "Horizontal padding `{{signal}}` of `{{value}}px` is below the minimum `{{min}}px` for interactive element `<{{tag}}>` in policy `{{policy}}`.",
|
|
40898
|
+
noReservedBlockSize: "Interactive element `<{{tag}}>` has no declared height (minimum `{{min}}px` required by policy `{{policy}}`). The element is content-sized and may not meet the touch-target threshold.",
|
|
40899
|
+
noReservedInlineSize: "Interactive element `<{{tag}}>` has no declared width (minimum `{{min}}px` required by policy `{{policy}}`). The element is content-sized and may not meet the touch-target threshold."
|
|
40900
|
+
};
|
|
40901
|
+
var INTERACTIVE_HTML_TAGS2 = /* @__PURE__ */ new Set(["button", "a", "input", "select", "textarea", "label", "summary"]);
|
|
40902
|
+
var INTERACTIVE_ARIA_ROLES2 = /* @__PURE__ */ new Set([
|
|
40903
|
+
"button",
|
|
40904
|
+
"link",
|
|
40905
|
+
"checkbox",
|
|
40906
|
+
"radio",
|
|
40907
|
+
"combobox",
|
|
40908
|
+
"listbox",
|
|
40909
|
+
"menuitem",
|
|
40910
|
+
"menuitemcheckbox",
|
|
40911
|
+
"menuitemradio",
|
|
40912
|
+
"option",
|
|
40913
|
+
"switch",
|
|
40914
|
+
"tab"
|
|
40915
|
+
]);
|
|
40916
|
+
function classifyInteractive(node, solid, element, layout) {
|
|
40917
|
+
const tag = node.tagName;
|
|
40918
|
+
if (tag !== null && INTERACTIVE_HTML_TAGS2.has(tag)) {
|
|
40919
|
+
if (tag === "input" || tag === "select" || tag === "textarea") return "input";
|
|
40920
|
+
return "button";
|
|
40921
|
+
}
|
|
40922
|
+
const roleAttr = getJSXAttributeEntity(solid, element, "role");
|
|
40923
|
+
if (roleAttr !== null && roleAttr.valueNode !== null) {
|
|
40924
|
+
const role = getStaticStringFromJSXValue(roleAttr.valueNode);
|
|
40925
|
+
if (role !== null && INTERACTIVE_ARIA_ROLES2.has(role)) return "button";
|
|
40926
|
+
}
|
|
40927
|
+
const hostRef = layout.hostElementRefsByNode.get(node) ?? null;
|
|
40928
|
+
if (hostRef !== null && hostRef.element.tagName !== null) {
|
|
40929
|
+
const hostTag = hostRef.element.tagName;
|
|
40930
|
+
if (INTERACTIVE_HTML_TAGS2.has(hostTag)) {
|
|
40931
|
+
if (hostTag === "input" || hostTag === "select" || hostTag === "textarea") return "input";
|
|
40932
|
+
return "button";
|
|
40933
|
+
}
|
|
40934
|
+
}
|
|
40935
|
+
return null;
|
|
40936
|
+
}
|
|
40937
|
+
function isVisuallyHidden(snapshot) {
|
|
40938
|
+
const position = readKnownNormalized(snapshot, "position");
|
|
40939
|
+
if (position !== "absolute" && position !== "fixed") return false;
|
|
40940
|
+
const node = snapshot.node;
|
|
40941
|
+
const opacityAttr = node.inlineStyleValues.get("opacity");
|
|
40942
|
+
if (opacityAttr === "0") return true;
|
|
40943
|
+
if (node.classTokenSet.has("opacity-0")) return true;
|
|
40944
|
+
return false;
|
|
40945
|
+
}
|
|
40946
|
+
var jsxLayoutPolicyTouchTarget = defineCrossRule({
|
|
40947
|
+
id: "jsx-layout-policy-touch-target",
|
|
40948
|
+
severity: "warn",
|
|
40949
|
+
messages: messages161,
|
|
40950
|
+
meta: {
|
|
40951
|
+
description: "Enforce minimum interactive element sizes per accessibility policy via resolved layout signals.",
|
|
40952
|
+
fixable: false,
|
|
40953
|
+
category: "css-a11y"
|
|
40954
|
+
},
|
|
40955
|
+
check(context, emit) {
|
|
40956
|
+
const policy = getActivePolicy();
|
|
40957
|
+
if (policy === null) return;
|
|
40958
|
+
const policyName = getActivePolicyName() ?? "";
|
|
40959
|
+
const { layout } = context;
|
|
40960
|
+
const elements = layout.elements;
|
|
40961
|
+
for (let i = 0; i < elements.length; i++) {
|
|
40962
|
+
const node = elements[i];
|
|
40963
|
+
if (!node) continue;
|
|
40964
|
+
const ref = readElementRef(layout, node);
|
|
40965
|
+
if (!ref) continue;
|
|
40966
|
+
const kind = classifyInteractive(node, ref.solid, ref.element, layout);
|
|
40967
|
+
if (kind === null) continue;
|
|
40968
|
+
const snapshot = collectSignalSnapshot(context, node);
|
|
40969
|
+
if (isVisuallyHidden(snapshot)) continue;
|
|
40970
|
+
const tag = node.tagName ?? node.tag ?? "element";
|
|
40971
|
+
checkDimension(
|
|
40972
|
+
snapshot,
|
|
40973
|
+
"height",
|
|
40974
|
+
kind === "button" ? policy.minButtonHeight : policy.minInputHeight,
|
|
40975
|
+
layout,
|
|
40976
|
+
node,
|
|
40977
|
+
emit,
|
|
40978
|
+
"heightTooSmall",
|
|
40979
|
+
messages161.heightTooSmall,
|
|
40980
|
+
tag,
|
|
40981
|
+
policyName
|
|
40982
|
+
);
|
|
40983
|
+
checkDimension(
|
|
40984
|
+
snapshot,
|
|
40985
|
+
"min-height",
|
|
40986
|
+
kind === "button" ? policy.minButtonHeight : policy.minInputHeight,
|
|
40987
|
+
layout,
|
|
40988
|
+
node,
|
|
40989
|
+
emit,
|
|
40990
|
+
"heightTooSmall",
|
|
40991
|
+
messages161.heightTooSmall,
|
|
40992
|
+
tag,
|
|
40993
|
+
policyName
|
|
40994
|
+
);
|
|
40995
|
+
checkDimension(
|
|
40996
|
+
snapshot,
|
|
40997
|
+
"width",
|
|
40998
|
+
kind === "button" ? policy.minButtonWidth : policy.minTouchTarget,
|
|
40999
|
+
layout,
|
|
41000
|
+
node,
|
|
41001
|
+
emit,
|
|
41002
|
+
"widthTooSmall",
|
|
41003
|
+
messages161.widthTooSmall,
|
|
41004
|
+
tag,
|
|
41005
|
+
policyName
|
|
41006
|
+
);
|
|
41007
|
+
checkDimension(
|
|
41008
|
+
snapshot,
|
|
41009
|
+
"min-width",
|
|
41010
|
+
kind === "button" ? policy.minButtonWidth : policy.minTouchTarget,
|
|
41011
|
+
layout,
|
|
41012
|
+
node,
|
|
41013
|
+
emit,
|
|
41014
|
+
"widthTooSmall",
|
|
41015
|
+
messages161.widthTooSmall,
|
|
41016
|
+
tag,
|
|
41017
|
+
policyName
|
|
41018
|
+
);
|
|
41019
|
+
if (kind === "button") {
|
|
41020
|
+
checkDimension(
|
|
41021
|
+
snapshot,
|
|
41022
|
+
"padding-left",
|
|
41023
|
+
policy.minButtonHorizontalPadding,
|
|
41024
|
+
layout,
|
|
41025
|
+
node,
|
|
41026
|
+
emit,
|
|
41027
|
+
"paddingTooSmall",
|
|
41028
|
+
messages161.paddingTooSmall,
|
|
41029
|
+
tag,
|
|
41030
|
+
policyName
|
|
41031
|
+
);
|
|
41032
|
+
checkDimension(
|
|
41033
|
+
snapshot,
|
|
41034
|
+
"padding-right",
|
|
41035
|
+
policy.minButtonHorizontalPadding,
|
|
41036
|
+
layout,
|
|
41037
|
+
node,
|
|
41038
|
+
emit,
|
|
41039
|
+
"paddingTooSmall",
|
|
41040
|
+
messages161.paddingTooSmall,
|
|
41041
|
+
tag,
|
|
41042
|
+
policyName
|
|
41043
|
+
);
|
|
41044
|
+
}
|
|
41045
|
+
const reservedSpace = readReservedSpaceFact(layout, node);
|
|
41046
|
+
const minBlock = kind === "button" ? policy.minButtonHeight : policy.minInputHeight;
|
|
41047
|
+
const minInline = kind === "button" ? policy.minButtonWidth : policy.minTouchTarget;
|
|
41048
|
+
if (!reservedSpace.hasUsableBlockDimension) {
|
|
41049
|
+
emitLayoutDiagnostic(
|
|
41050
|
+
layout,
|
|
41051
|
+
node,
|
|
41052
|
+
emit,
|
|
41053
|
+
jsxLayoutPolicyTouchTarget.id,
|
|
41054
|
+
"noReservedBlockSize",
|
|
41055
|
+
messages161.noReservedBlockSize,
|
|
41056
|
+
"warn",
|
|
41057
|
+
{ tag, min: String(minBlock), policy: policyName }
|
|
41058
|
+
);
|
|
41059
|
+
}
|
|
41060
|
+
if (!reservedSpace.hasUsableInlineDimension) {
|
|
41061
|
+
emitLayoutDiagnostic(
|
|
41062
|
+
layout,
|
|
41063
|
+
node,
|
|
41064
|
+
emit,
|
|
41065
|
+
jsxLayoutPolicyTouchTarget.id,
|
|
41066
|
+
"noReservedInlineSize",
|
|
41067
|
+
messages161.noReservedInlineSize,
|
|
41068
|
+
"warn",
|
|
41069
|
+
{ tag, min: String(minInline), policy: policyName }
|
|
41070
|
+
);
|
|
41071
|
+
}
|
|
41072
|
+
}
|
|
41073
|
+
}
|
|
41074
|
+
});
|
|
41075
|
+
function checkDimension(snapshot, signal, min, layout, node, emit, messageId, template, tag, policyName) {
|
|
41076
|
+
const px = readKnownPx(snapshot, signal);
|
|
41077
|
+
if (px === null) return;
|
|
41078
|
+
if (px >= min) return;
|
|
41079
|
+
emitLayoutDiagnostic(
|
|
41080
|
+
layout,
|
|
41081
|
+
node,
|
|
41082
|
+
emit,
|
|
41083
|
+
jsxLayoutPolicyTouchTarget.id,
|
|
41084
|
+
messageId,
|
|
41085
|
+
template,
|
|
41086
|
+
"warn",
|
|
41087
|
+
{
|
|
41088
|
+
signal,
|
|
41089
|
+
value: formatRounded(px),
|
|
41090
|
+
min: String(min),
|
|
41091
|
+
tag,
|
|
41092
|
+
policy: policyName
|
|
41093
|
+
}
|
|
41094
|
+
);
|
|
41095
|
+
}
|
|
41096
|
+
|
|
41034
41097
|
// src/cross-file/rules/index.ts
|
|
41035
41098
|
var rules3 = [
|
|
41036
41099
|
jsxNoUndefinedCssClass,
|
|
@@ -41062,7 +41125,8 @@ var rules3 = [
|
|
|
41062
41125
|
cssLayoutOverflowModeToggleInstability,
|
|
41063
41126
|
cssLayoutBoxSizingToggleWithChrome,
|
|
41064
41127
|
cssLayoutContentVisibilityNoIntrinsicSize,
|
|
41065
|
-
cssLayoutConditionalOffsetShift
|
|
41128
|
+
cssLayoutConditionalOffsetShift,
|
|
41129
|
+
jsxLayoutPolicyTouchTarget
|
|
41066
41130
|
];
|
|
41067
41131
|
|
|
41068
41132
|
// src/cross-file/plugin.ts
|