Skip to content

Commit

Permalink
feat: add autofix for logical to inline properties in valid-styles ru…
Browse files Browse the repository at this point in the history
…le (facebook#805)
  • Loading branch information
mellyeliu authored and aminaopio committed Dec 22, 2024
1 parent 2349be1 commit 3cc5bbc
Show file tree
Hide file tree
Showing 2 changed files with 125 additions and 1 deletion.
81 changes: 81 additions & 0 deletions packages/eslint-plugin/__tests__/stylex-valid-styles-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,21 @@ eslintTester.run('stylex-valid-styles', rule.default, {
}
});
`,
`
import stylex from "stylex";
const styles = stylex.create({
validStyle: {
marginInlineStart: "10px",
marginInlineEnd: "5px",
marginInline: "15px",
marginBlock: "20px",
paddingInlineStart: "8px",
paddingInlineEnd: "12px",
paddingInline: "10px",
paddingBlock: "16px",
},
});
`,
`
import stylex from 'stylex';
const start = 'start';
Expand Down Expand Up @@ -583,6 +598,72 @@ eslintTester.run('stylex-valid-styles', rule.default, {
},
],
},
{
code: `
import stylex from 'stylex';
const styles = stylex.create({
invalidStyle: {
marginStart: '10px',
marginEnd: '5px',
marginHorizontal: '15px',
marginVertical: '15px',
paddingStart: '10px',
paddingEnd: '5px',
paddingHorizontal: '5px',
paddingVertical: '15px',
},
});
`,
errors: [
{
message:
'The key "marginStart" is not a standard CSS property. Did you mean "marginInlineStart"?',
},
{
message:
'The key "marginEnd" is not a standard CSS property. Did you mean "marginInlineEnd"?',
},
{
message:
'The key "marginHorizontal" is not a standard CSS property. Did you mean "marginInline"?',
},
{
message:
'The key "marginVertical" is not a standard CSS property. Did you mean "marginBlock"?',
},
{
message:
'The key "paddingStart" is not a standard CSS property. Did you mean "paddingInlineStart"?',
},
{
message:
'The key "paddingEnd" is not a standard CSS property. Did you mean "paddingInlineEnd"?',
},
{
message:
'The key "paddingHorizontal" is not a standard CSS property. Did you mean "paddingInline"?',
},
{
message:
'The key "paddingVertical" is not a standard CSS property. Did you mean "paddingBlock"?',
},
],
output: `
import stylex from 'stylex';
const styles = stylex.create({
invalidStyle: {
marginInlineStart: '10px',
marginInlineEnd: '5px',
marginInline: '15px',
marginBlock: '15px',
paddingInlineStart: '10px',
paddingInlineEnd: '5px',
paddingInline: '5px',
paddingBlock: '15px',
},
});
`,
},
{
code: "import stylex from 'stylex'; stylex.create({default: {textAlign: 'lfet'}});",
errors: [
Expand Down
45 changes: 44 additions & 1 deletion packages/eslint-plugin/src/stylex-valid-styles.js
Original file line number Diff line number Diff line change
Expand Up @@ -1595,6 +1595,17 @@ const SupportedVendorSpecificCSSProperties = {
),
};

const validStyleMapping: $ReadOnly<{ [key: string]: ?string }> = {
marginStart: 'marginInlineStart',
marginEnd: 'marginInlineEnd',
marginHorizontal: 'marginInline',
marginVertical: 'marginBlock',
paddingStart: 'paddingInlineStart',
paddingEnd: 'paddingInlineEnd',
paddingHorizontal: 'paddingInline',
paddingVertical: 'paddingBlock',
};

const SVGProperties = {
colorInterpolation: makeUnionRule('auto', 'sRGB', 'linearRGB'),
// colorRendering: color,
Expand Down Expand Up @@ -2292,6 +2303,7 @@ const stylexValidStyles = {
meta: {
type: 'problem',
hasSuggestions: true,
fixable: 'code',
docs: {
descriptions: 'Enforce that you create valid stylex styles',
category: 'Possible Errors',
Expand Down Expand Up @@ -2635,10 +2647,41 @@ const stylexValidStyles = {
const distance = getDistance(key, cssProp, 2);
return distance <= 2;
});

const replacementKey =
style.key.type === 'Identifier' && validStyleMapping[style.key.name]
? validStyleMapping[style.key.name]
: style.key.type === 'Literal' &&
typeof style.key.value === 'string' &&
validStyleMapping[style.key.value]
? validStyleMapping[style.key.value]
: null;

let originalKey = '';

if (style.key.type === 'Identifier') {
originalKey = style.key.name;
} else if (
style.key.type === 'Literal' &&
typeof style.key.value === 'string'
) {
originalKey = style.key.value;
}

return context.report({
node: style.key,
loc: style.key.loc,
message: 'This is not a key that is allowed by stylex',
message:
replacementKey &&
(style.key.type === 'Identifier' || style.key.type === 'Literal')
? `The key "${originalKey}" is not a standard CSS property. Did you mean "${replacementKey}"?`
: 'This is not a key that is allowed by stylex',
fix: (fixer) => {
if (replacementKey) {
return fixer.replaceText(style.key, replacementKey);
}
return null;
},
suggest:
closestKey != null
? [
Expand Down

0 comments on commit 3cc5bbc

Please sign in to comment.