Skip to content

Commit a88fceb

Browse files
authored
feat: Adds negative z-index rule to stylelint (#4)
1 parent 9d4dc30 commit a88fceb

File tree

3 files changed

+108
-1
lines changed

3 files changed

+108
-1
lines changed
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2+
// SPDX-License-Identifier: Apache-2.0
3+
import { describe, test, expect } from "vitest";
4+
import stylelint from "stylelint";
5+
6+
import { configBasedir } from "./common.js";
7+
8+
// This is for prettier format: https://github.com/prettier/prettier/issues/2330
9+
// String.raw is an identity function in this context
10+
const css = String.raw;
11+
12+
function runPlugin(code) {
13+
return stylelint.lint({
14+
code,
15+
configBasedir,
16+
config: {
17+
plugins: ["../z-index-value-constraint.js"],
18+
rules: {
19+
"@cloudscape-design/z-index-value-constraint": [true],
20+
},
21+
},
22+
});
23+
}
24+
25+
describe("z-index value contstraint rule", () => {
26+
test("allows non integer z-index values", async () => {
27+
const result = await runPlugin(css`
28+
.styled-circle-motion {
29+
@include styles.with-motion {
30+
z-index: some.$variable;
31+
}
32+
}
33+
`);
34+
35+
expect(result.errored).toBe(false);
36+
});
37+
38+
test.each([0, 1000])("allows non negative z-index values: %s", async zIndexValue => {
39+
const result = await runPlugin(css`
40+
.styled-circle-motion {
41+
@include styles.with-motion {
42+
z-index: ${zIndexValue};
43+
}
44+
}
45+
`);
46+
47+
expect(result.errored).toBe(false);
48+
});
49+
50+
test("does not allow negative z-index values", async () => {
51+
const result = await runPlugin(css`
52+
.styled-circle-motion {
53+
@include styles.with-motion {
54+
z-index: -10;
55+
}
56+
}
57+
`);
58+
59+
expect(result.errored).toBe(true);
60+
expect(result.results[0].warnings[0].text).toBe(`Avoid using negative z-index values: -10.
61+
This can cause the element to disappear behind its container's background color. (@cloudscape-design/z-index-value-constraint)`);
62+
});
63+
});

src/stylelint/index.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,6 @@
33
import licenseHeaders from "./license-headers.js";
44
import noImplicitDescendant from "./no-implicit-descendant.js";
55
import noMotionOutsideOfMixin from "./no-motion-outside-of-mixin.js";
6+
import zIndexValueConstraint from "./z-index-value-constraint.js";
67

7-
export default [noImplicitDescendant, noMotionOutsideOfMixin, licenseHeaders];
8+
export default [noImplicitDescendant, noMotionOutsideOfMixin, licenseHeaders, zIndexValueConstraint];
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2+
// SPDX-License-Identifier: Apache-2.0
3+
import stylelint from "stylelint";
4+
5+
const ruleName = "@cloudscape-design/z-index-value-constraint";
6+
7+
const messages = stylelint.utils.ruleMessages(ruleName, {
8+
noNegativeZIndex: zIndexValue => {
9+
return `Avoid using negative z-index values: ${zIndexValue}.
10+
This can cause the element to disappear behind its container's background color.`;
11+
},
12+
});
13+
14+
function zIndexValueConstraint(enabled) {
15+
if (!enabled) {
16+
return;
17+
}
18+
19+
return function (root, result) {
20+
root.walkDecls(function (decl) {
21+
if (decl.prop !== "z-index") return;
22+
23+
const zIndexValue = Number(decl.value);
24+
25+
// If the z-index value is not a number (e.g. variable), don't throw an error.
26+
if (Number.isNaN(zIndexValue)) return;
27+
28+
if (zIndexValue < 0) {
29+
stylelint.utils.report({
30+
result,
31+
ruleName,
32+
message: messages.noNegativeZIndex(zIndexValue),
33+
node: decl,
34+
});
35+
}
36+
});
37+
};
38+
}
39+
40+
zIndexValueConstraint.ruleName = ruleName;
41+
zIndexValueConstraint.messages = messages;
42+
43+
export default stylelint.createPlugin(ruleName, zIndexValueConstraint);

0 commit comments

Comments
 (0)